Tuesday, April 26, 2016

Optimize ADF HTTP Response Size with ChangeEventPolicy

You should read this post, if you are looking how to reduce ADF HTTP response size. This can be important for ADF application performance tuning, to improve PPR request response time. By default in ADF 12.2.1, iterator is assigned with ChangeEventPolicy = ppr. This works great for UI component bindings refresh, no need to set individual partial triggers. On other side, this generates extra content in ADF HTTP response and eventually increases response size. I would recommend to use ChangeEventPolicy = ppr, only when its really needed - dynamic forms, with unknown refresh dependencies. Otherwise set ChangeEventPolicy = none, to generate smaller response.

I will demonstrate below the difference for ADF HTTP response with ChangeEventPolicy=ppr/none. First let's take a look into page load response size:

Page contains list component and form. Both are based on two different iterators, set with ChangeEventPolicy = ppr. This generates AdfPage.PAGE.updateAutoPPRComponents calls for each UI item, referencing attributes from the iterator. In complex screens, this adds significant amount of extra text to the response, could increase size even by half:

Partial response also contains same calls added to the response. Select list item:

Each item from the form will be referenced by JavaScript call, to register it for refresh:

Let's change it to ChangeEventPolicy = none. Set it for both iterators:

We should set refresh dependencies manually. Form block must be set with PartialTrigger, referencing list component - to refresh, when list selection changes:

Next/Previous buttons dependency also must be set, to change form row:

With manual refresh dependency changes, there are no extra calls added to ADF HTTP response, reducing overall response size:

Same applies for PPR response:

Download sample application - ChangeEventPolicyPPRApp.zip.

Sunday, April 17, 2016

ADF 12c Custom Property Groovy and AllowUntrustedScriptAccess Annotation

To execute Groovy expression in ADF 12c (to call Java method from Groovy), you must specify trusted mode. Read more about it in my previous post - ADF BC 12c New Feature - Entity-Level Triggers. Setting mode to trusted, works in most of the cases. It doesn't work if we want to execute Groovy expression (calling Java method in ViewRow or Entity class) for custom property. In a case of custom property and Groovy calling custom method, we need to annotate Java class with AllowUntrustedScriptAccess. This makes a trick and Groovy expression can call custom method.

To demonstrate the use case, I was using mandatory property. This is standard property to control if attribute is required or no. By default, mandatory property is static, but we can make it dynamic with Groovy expression. I have implemented a rule, where Salary attribute is required, if value is more than 5000:

Salary is not required, if value is less than 5000. This is just example, you can implement more complex logic:

There is a method in ViewRow class, to calculate required property for Salary attribute:

Method is callable from custom property Groovy expression, as we have set annotation AllowUntrustedScriptAccess for ViewRow class. Annotation definition, must list all allowed methods:

Here you can see Groovy expression, to call ViewRow class method - mandatory. Expression is assigned for custom property, this will be referenced from ADF UI:

There is issue with JDEV 12c, it fails to parse custom properties set with Groovy expressions. It fails to parse and removes custom property from the code. To prevent such behavior, specify empty string for custom property value (this will allow to keep Groovy expression):

Luckily in this case of mandatory check, JDEV by default generates mandatory property for ADF UI component. We simply override its original value with custom property and calculate new value in custom trusted method, referenced by Groovy expression:

Download sample application - ADF12cGroovyCustomPropertyApp.zip.

Sunday, April 10, 2016

Monitoring ADF 12c Client Request Time with Click History

You must be excited to read this post, I will describe one very useful feature, available in ADF 12c. This feature - Click History. You can follow steps described by Duncan Mills, to enable and read click history data in server log. There is one more option available - we can read click history data from ADF request (captured by filter class) and log it in custom way (for later analysis). Click history gives such information as client request start/end time (you can calculate client request duration), component client ID, component type, action event type, etc. All this is useful to understand application performance perceived by the client.

Download sample application - DashboardApp.zip (it contains JET libraries, to render JET content within ADF). To test click history and view generated statistics, click on any button and selection component. Click history returns previous action statistics. Let's click on Cancel button:

You should see similar XML message printed in the log (click history statistics data):

To view it in readable way, you can copy it into XML file and format in JDEV:

Logged properties, useful to track client request performance:

1. CID - ECID number, identifies request
2. CST - client request start time
3. CET - client request end time
4. ETY - client event type
5. CLD - client component ID
6. CTY - client component type

XML message can be parsed and property values can be logged to DB for performance history analysis.

To enable click history, you only need to set parameter (true) in web.xml oracle.adf.view.faces.context.ENABLE_ADF_EXECUTION_CONTEXT_PROVIDER:

To read click history data from ADF request, we need to define custom filter in web.xml. Register filter under Faces Servlet:

In the filter, override doFilter and retrieve oracle.adf.view.rich.monitoring.UserActivityInfo parameter (this will return click history XML string, as above):

Thursday, April 7, 2016

ADF BC View Criteria Query Execution Mode = Both

View Criteria is set to execute in Database mode by default. There is option to change execution mode to Both. This would execute query and fetch results from database and from memory.  Such query execution is useful, when we want to include newly created (but not commited yet) row into View Criteria result. Newly created row will be included into View Criteria resultset.

Download sample application - ViewCriteriaModeApp.zip. JobsView in sample application is set with query execution mode for View Criteria to Both:

I'm using JobsView in EmployeesView through View Accessor. If data from another VO is required, you can fetch it through View Accessor. View Accessor is configured with View Criteria, this means it will be automatically filtered (we only need to set Bind Variable value):

Employees VO contains custom method, where View Accessor is referenced. I'm creating new row and executing query with bind variable (primary key for newly created row). View Criteria is set to execution mode Both, this allows to retrieve newly created row (not commited yet) after search:

View Criteria execution mode Both is useful, when we want to search without loosing newly created rows.