Welcome!

Apache Authors: Pat Romanski, Liz McMillan, Elizabeth White, Christopher Harrold, Janakiram MSV

Related Topics: Java IoT, Recurring Revenue, Apache

Java IoT: Blog Feed Post

Configuring Apache JMeter for Oracle's ADF 11g

Additional configurations required for JMeter

Sometime back I blogged about Stress & load testing web applications (even ADF & Apex) using Apache JMeter. That post dealt with the generic setup of recording a web session and then replaying under load via JMeter.

When considering using JMeter for JDeveloper 11g ADF applications there are additional JMeter configuration steps required beyond that detailed in the original post. As per the original post ADF passes around cookies to store the JSESSIONID, and you can use JMeter's HTTP Cookie Manager to correctly handle the cookie. However ADF also makes use of a number of parameters passed as HTTP POST parameters and URL parameters. On running an ADF application you'll often see URL parameters like _adf.ctrl-state, _afrLoop, and embedded within the HTTP bodies variables such as javax.faces.ViewState, used by ADF to coordinate state with the browser session. In order for JMeter to simulate multiple user sessions it needs to be correctly configured to handle these too, capturing and carrying the unique values for each session in the load test.

The following post lists the additional configurations required for JMeter beyond those described in the original post. As noted in the original post the easiest way to setup your JMeter Test Plan is to record an existing ADF session through JMeter's HTTP Proxy Server and I haven't bothered to reiterate those instructions here. In turn I've taken no effort to explain the JMeter features we're utilizing to do this; if you want to learn about the relevant JMeter features consult the JMeter User Manual.

Caveat for ADF 10g users: You'll note above I specifically stated JDeveloper 11g ADF, not 10g. I haven't tested any of the following settings for JDev 10g and I don't believe they'll work, as if memory serves me correctly the POST and URL parameters mechanisms changed between versions. However the following notes may give you enough information to dig around in a running 10g ADF application, looking at the HTTP Requests to work out what parameters to work with.

JMeter ADF Required Configurations
The following lists five additional objects and their settings. You need only create one of each for each Thread Group. The end result will look something like this:


a) HTTP Cookie Manager

Create via Test Plan -> Thread Group -> Right Click -> Add -> Config Element -> HTTP Cookie Manager

Name: HTTP Cookie Manager
Clear cookies each iteration: Selected


b) User Defined Variables

Create via Test Plan -> Thread Group -> Right Click -> Add -> Config Element -> User Defined Variables

Name: ADF Variables
Variable Name: afrLoop
Variable Name: afrWindowId
Variable Name: jsessionId
Variable Name: adf.ctrl-state
Variable Name: javax.faces.ViewState


No initial values.
c) Regular Expression Extractor #1

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor

Name: adf.ctrl-state Extractor
Response Field to Check: Body
Reference Name: adf.ctrl-state
Regular Expression: _adf.ctrl-state=([-_0-9A-Za-z!]{10,13})
Template: $1$
Match No.: 1
Default Value: n/a


Take notice that the variable name does not include an underscore in it's name unlike the actual parameter _adf.ctrl-state.

d) Regular Expression Extractor #2

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor

Name: afrLoop Extractor
Response Field to Check: Body
Reference Name: afrLoop
Regular Expression: _afrLoop=([-_0-9A-Za-z]{13,16})
Template: $1$
Match No.: 1
Default Value: n/a


Take notice that the variable name does not include an underscore in it's name unlike the actual parameter _afrLoop.

d) Regular Expression Extractor #3

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor

Name: afrWindowId Extractor
Response Field to Check: Body
Reference Name: afrWindowId
Regular Expression: window.name='([-_0-9A-Za-z!]{10,13})'
Template: $1$
Match No.: 1
Default Value: n/a


e) Regular Expression Extractor #4

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor

Name: javax.faces.ViewState Extractor
Response Field to Check: Body
Reference Name: javax.faces.ViewState
Regular Expression: <input type="hidden" name="javax\.faces\.ViewState" value="!(.+?)">
Template: $1$
Match No.: 1
Default Value: n/a


f) Regular Expression Extractor #5

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor

Name: jsesssionId Extractor
Response Field to Check: Body
Reference Name: jsessionId
Regular Expression: ;jsessionid=([-_0-9A-Za-z!]{63})
Template: $1$
Match No.: 1
Default Value: n/a


Recorded HTTP Request Changes

After recording an ADF session in JMeter, and setting up the variables above, you'll note in the recorded HTTP Requests numerous references to the same named variables as HTTP parameters. Yet the recorded HTTP Requests include the parameters' values for the recorded session, which simply won't work when we replay the session as the values will have changed.


It is therefore necessary to identify all locations where the parameters exist in the recorded session HTTP Requests and substitute references to your variables.

a) HTTP Request – Path – any path that makes reference to jsessionId must be changed.

ie: /SageApp/faces/ViewEvents;jsessionId=${jsessionId}


b) HTTP Request – Path – ditto any path that makes reference to _adf.ctrl-state must be changed.

ie. /SageApp/faces/ViewEvents?_adf.ctrl-state=${adf.ctrl-state}


You can also change this in the name if you want but it wont make a different to the overall result, the name is for show only.

c) HTTP Request – Parameters – for any of the following parameters:

_adf.ctrl-state
_afrLoop
_afrWindowId (* see exception at the end of this step)

...for their values substitute the relevant variable. The following example shows the values for the afrLoop and adf.ctrl-state replaced:


However there is one exception with _afrWindowId. In one of the initial requests its value will be the literal string "null" (see the picture in step (a) for an example). Do not replace this, leave it as null.

d) HTTP Request – Parameters – for the "javax.faces.ViewState" parameter, ditto replace its values. Note it is necessary to put a not (negate) symbol in front of it:

ie. !${javax.faces.ViewState}

In addition by default the "Encode?" parameter will be on for each javax.faces.ViewState. Instead turn it off for each:


e) HTTP Request – Parameters – for the "unique" parameter, occurring in the Path and request parameters replace it with the following notation:

${__javaScript(new Date().getTime(),DUMMY)}

Note there is no JMeter user variable for this, we just write it straight into the unique value.

f) HTTP Header Manager Referer – if the HTTP session has been recorded via JMeter's HTTP Proxy, each HTTP Request will include a sub-element HTTP Header Manager that includes an element called Referer. You'll note it will have hardcoded many of the parameters discussed above. However I don't think ADF requires the Referer element and you can just ignore it or delete it from every HTTP Header Manager.

Assertions

Once you've completed the above setup and want to run your load test via JMeter, it is important to see that the test is working correctly. One way to do this is to create a View Results Tree (Test Plan -> Thread Group -> Right Click -> Add -> Listener -> View Results Tree) that allows you to inspect the response of each HTTP Request. If you then see HTTP Request responses in red this indicates a HTTP error code response (!= 200). However it's also necessary to inspect each response even if they are green to see if there's a valid response returned carrying an error message. There is definitely a small knack to differentiating between the different type of failures in an ADF application, which you'll become familiar with on some experience.

In order to save you having to look for the same problems for each test-run, you can create a Response Assertion (Test Plan -> Thread Group -> Add -> Assertions -> Response Assertion) to look for specific errors in the responses. From my own ADF experience you want to setup a Response Assertion with the following values:

Which Samples to Test: Main Sample Only
Response Field to Test: Text Response
Pattern Matching Rules: Contains
Not: Selected
Patterns to Test #1: The following exception occurred
Patterns to Test #2: Server Exception during PPR
Patterns to Test #3: ADFC-12000
Patterns to Test #4: java.net.SocketException
Patterns to Test #5: java.io.IOException


This isn't a definitive list, and in turn there may be specific errors that you may want to pick up for your application.

Sample JMeter file
Readers can download a sample JMeter JMX file for ADF here with the configurations already setup.

Finishing Comment
I haven't had the chance to test this in every ADF scenario or application. It's possible in your application, dependent on the components you're using or some other trick of ADF, that I've missed one of the state values it wants the browser to carry. With the post above hopefully you'll get an idea of the majority and be able to identify more. I'd appreciate it if anybody finds more that we need to cater for please post a comment with your findings to assist other readers.

Read the original blog entry...

More Stories By Chris Muir

Chris Muir, an Oracle ACE Director, senior developer and trainer, and frequent blogger at http://one-size-doesnt-fit-all.blogspot.com, has been hacking away as an Oracle consultant with Australia's SAGE Computing Services for too many years. Taking a pragmatic approach to all things Oracle, Chris has more recently earned battle scars with JDeveloper, Apex, OID and web services, and has some very old war-wounds from a dark and dim past with Forms, Reports and even Designer 100% generation. He is a frequent presenter and contributor to the local Australian Oracle User Group scene, as well as a contributor to international user group magazines such as the IOUG and UKOUG.

IoT & Smart Cities Stories
The deluge of IoT sensor data collected from connected devices and the powerful AI required to make that data actionable are giving rise to a hybrid ecosystem in which cloud, on-prem and edge processes become interweaved. Attendees will learn how emerging composable infrastructure solutions deliver the adaptive architecture needed to manage this new data reality. Machine learning algorithms can better anticipate data storms and automate resources to support surges, including fully scalable GPU-c...
Machine learning has taken residence at our cities' cores and now we can finally have "smart cities." Cities are a collection of buildings made to provide the structure and safety necessary for people to function, create and survive. Buildings are a pool of ever-changing performance data from large automated systems such as heating and cooling to the people that live and work within them. Through machine learning, buildings can optimize performance, reduce costs, and improve occupant comfort by ...
The explosion of new web/cloud/IoT-based applications and the data they generate are transforming our world right before our eyes. In this rush to adopt these new technologies, organizations are often ignoring fundamental questions concerning who owns the data and failing to ask for permission to conduct invasive surveillance of their customers. Organizations that are not transparent about how their systems gather data telemetry without offering shared data ownership risk product rejection, regu...
René Bostic is the Technical VP of the IBM Cloud Unit in North America. Enjoying her career with IBM during the modern millennial technological era, she is an expert in cloud computing, DevOps and emerging cloud technologies such as Blockchain. Her strengths and core competencies include a proven record of accomplishments in consensus building at all levels to assess, plan, and implement enterprise and cloud computing solutions. René is a member of the Society of Women Engineers (SWE) and a m...
Poor data quality and analytics drive down business value. In fact, Gartner estimated that the average financial impact of poor data quality on organizations is $9.7 million per year. But bad data is much more than a cost center. By eroding trust in information, analytics and the business decisions based on these, it is a serious impediment to digital transformation.
Digital Transformation: Preparing Cloud & IoT Security for the Age of Artificial Intelligence. As automation and artificial intelligence (AI) power solution development and delivery, many businesses need to build backend cloud capabilities. Well-poised organizations, marketing smart devices with AI and BlockChain capabilities prepare to refine compliance and regulatory capabilities in 2018. Volumes of health, financial, technical and privacy data, along with tightening compliance requirements by...
Predicting the future has never been more challenging - not because of the lack of data but because of the flood of ungoverned and risk laden information. Microsoft states that 2.5 exabytes of data are created every day. Expectations and reliance on data are being pushed to the limits, as demands around hybrid options continue to grow.
Digital Transformation and Disruption, Amazon Style - What You Can Learn. Chris Kocher is a co-founder of Grey Heron, a management and strategic marketing consulting firm. He has 25+ years in both strategic and hands-on operating experience helping executives and investors build revenues and shareholder value. He has consulted with over 130 companies on innovating with new business models, product strategies and monetization. Chris has held management positions at HP and Symantec in addition to ...
Enterprises have taken advantage of IoT to achieve important revenue and cost advantages. What is less apparent is how incumbent enterprises operating at scale have, following success with IoT, built analytic, operations management and software development capabilities - ranging from autonomous vehicles to manageable robotics installations. They have embraced these capabilities as if they were Silicon Valley startups.
As IoT continues to increase momentum, so does the associated risk. Secure Device Lifecycle Management (DLM) is ranked as one of the most important technology areas of IoT. Driving this trend is the realization that secure support for IoT devices provides companies the ability to deliver high-quality, reliable, secure offerings faster, create new revenue streams, and reduce support costs, all while building a competitive advantage in their markets. In this session, we will use customer use cases...