Wednesday, July 24, 2013

There is very handy feature available in ADF 12c - option to display predefined information, if current user is not authorized to view given region. Predefined information comes from dedicated ADF Task Flow with JSF fragment containing user friendly message.

In my example, there is one task flow configured to be rendered only for users assigned with finance-role:

Test user redsam is not assigned with finance-role, this is done for test purpose - to see how unauthorized region will be rendered:

As I mentioned earlier, there is one dedicated task flow created to be rendered instead of blank screen, when original task flow is not authorized to be rendered - unauthorized-flow:

Keep in mind - such task flow must be granted with anonymous or authenticated access to be accessible for anyone in the system.

JSF fragment from dedicated task flow contains simple text in this example, you may create something more fancy:

The key thing - configure dedicated ADF task flow to be considered by ADF runtime as the one to be rendered when original one is not accessible. This is done in adf-config.xml file. Under Controller section, make sure to point Unauthorized Region Taskflow to point to the ADF task flow definition:

On runtime, we can login with redsam user:

First region with departments data is rendered, second region is not authorized to be displayed - dedicated ADF region is rendered instead with text - Task flow access is denied:

Page is implemented with Panel Dashboard, two regions are located next to each other:

Tuesday, July 23, 2013

One of the new ADF BC features in ADF 12c - Row Finder. Row Finder acts as a helper for View Criteria to pass bind variable values and call query functionality. Important technical detail - instead of changing original rowset displayed on ADF UI, Row Finder creates and returns new rowset for results. This allows to search and get results with the same VO instance in parallel to the data displayed on ADF UI, without affecting original rowset accessed through bindings. At the moment it is possible to invoke Row Finder only programmatically through ADF BC API.

Here you can download sample application where Row Finder is implemented - RowFinderApp.zip.

When implementing Row Finder, firstly you need to define View Criteria. Here is View Criteria from sample application - filtering by First Name:

Once View Criteria is in place, you can go and define Row Finder (you must have View Criteria defined first). Set mapping between Bind Variables included into View Criteria and Attributes from where value is supposed to be supplied on runtime:

Later when invoking Row Finder through ADF BC API, we will need to set Attribute List with Attribute name and value pair.

There is custom method created in VO implementation class, this is where we call Row Finder:

Here is Row Finder invocation API example. Row Finder is invoked through execute(AttributeList, VO) method. We need to supply value for attribute name defined in Row Finder wizard previously. I'm getting value from current row. As you can see - Row Finder creates and returns another row iterator, without affecting original rowset of current VO instance. Basically it call new SQL query:

Custom method returns value - number of rows matching First Name from current row and is referenced from ADF bindings:

Later we display number of filtered rows in the popup on ADF UI. Here you can see example for 'David' - 3 rows located:

There are 9 rows for 'D':

The best of all - displayed rowset is not affected, we can move to another record and see that it comes from original rowset - 'Bruce':

Tuesday, July 16, 2013

ADF 12c developer guide describes new ADF BC tuning property - Disconnect Application Module Upon Reaching Maximum Connection Threshold (jbo.ampool.connection_threshold). I was doing a bit of research around this property and testing how it works. It looks to me - it doesn't work yet, as it should. You should be careful using jbo.ampool.connection_threshold. As per developer guide, connection threshold functionality is enabled when threshold value is set to positive number. Once AM pool will grow more than this number, ADF BC will start disconnecting and releasing DB connections for the least used AM's. Disconnect will happen during AM pool cleanup, developer guide recommends to configure shorter pool cleanup interval (jbo.ampool.monitorsleepinterval). With normal ADF BC DB pooling enabled, disconnect will happen after each request. In theory connection threshold is supposed to optimize this and do disconnect only when exceeding configured threshold and during pool cleanup cycle. However this doesn't seem to work, at least based on my test.

My test was based on these tuning settings:

- Minimum Available Size changed to be 0, all AM instances will be cleaned

- Idle Instance Timeout property is kept default 10 minutes on purpose, in order to force earlier disconnect from jbo.ampool.connection_threshold

- Disconnect Application Module Upon Release is not set. As it is stated in the developer guide, when positive threshold value is set - DB connection disconnect mode is set automatically (meaning no need to set it by yourself directly)

Connection threshold (jbo.ampool.connection_threshold) is set to be 3. Meaning when there will be more than 3 active AM's with DB connections, disconnect mechanism should start during next pool cleanup cycle:

I was running this test with 6 concurrent users, starting with the first user - completing first user actions and then starting with the next user. By the time 6th user starts his session, 30 seconds interval from the first user session was passed - pool monitor should disconnect exceeded number of connections - but this didn't happen. All 6 connections still remain reserved, with connection threshold set to 3 and pool monitor interval set to 30 seconds:

Here you can download sample application I was using for this test - ADFBCConnThresholdApp.zip. This tuning option looks to me very powerful for performance optimization and more optimal DB connection usage, hopefully it will be fixed soon and we could use it. Or may be my test was wrong, and it works already - let's see if we get more input regarding this tuning option.

Sunday, July 14, 2013

There is new exciting feature available in JDeveloper 12c - Explore Dependencies. This works across all MVC layers (fragments, pages, task flows, bindings, model) and shows visual dependencies and connections between various files from your application. Below I will give couple of examples for typical ADF application.

1. DataBindings.cpx file dependencies

This shows all fragments/pages and page definition files included into DataBindings.cpx. You can expand page definition further and will see all VO's referenced from that page definition. Expand VO and will be able to see referenced EO's, VO links, etc.:

2. ADF/JSF fragment dependencies

You can see ADF task flow where selected fragment belongs and DataBindings.cpx file where it is referenced:

3. Page Definiton dependencies

Here we can get a list of referenced VO's, explore further and get a list of referenced EO's by selected VO:

4. View Object dependencies

Dependencies diagram brings very useful info and displays page definition and AM files where current VO is included:

Saturday, July 13, 2013

First test I did with ADF 12c was to run apps developed with previous releases ADF 11g R1/R2. Migration was very smooth, no issues so far. Applications are migrated just with single click, no matter if based on JSPX or Faces.

In this post I'm going to publish two applications migrated from my previous posts. You can download two ADF 12c samples from here - adf12c_app.zip.

Monday, July 8, 2013

There might be cases when usage of declarative ADF BC View Criteria features will be not enough to implement complex filtering, as for example see my previous post - Bug in View Criteria - Joining Multiple Criteria Item Groups Doesn't Work. I will describe in this post how you can reuse complex WHERE clause and use ADF View Criteria to capture user criteria params only.

The trick is described in this sample application - CustomCriteriaOperatorApp_v3.zip. Along with View Criteria type - non required Bind Variables, I have defined one marked as required (WHERE type). Bind Variable - regionIdVar is used directly from static WHERE clause (marked as Required):

Static WHERE clause can be complex one, and usually there is no option to define complex WHERE clause with only declarative features offered by View Criteria.

Make sure to set Hide flag for required Bind Variable, otherwise it will be rendered as required criteria field in ADF Query:

We need to capture criteria parameter from ADF Query and initialize Bind Variable, this can be done through transient attribute defined in VO. There is no need to passivate this attribute explicitly, because framework will take care and passivate bind variable value automatically:

This sample defined WHERE clause with two separate groups connected with AND. Second group is using bind variable - regionIdVar:

Here you can see how bind variable is initialized, it will get value from transient RegionId field rendered by ADF Query:

Other bind variables are defined as View Criteria type, will be appended to WHERE clause dynamically on runtime:

RegionId is retrieved from ADF Query and set for static WHERE clause, while FirstName criteria value is appended dynamically:

Sunday, July 7, 2013

If you plan to use declarative ADF BC View Criteria features, you should keep in mind one bug related to complex View Criteria implementation with multiple joined criteria items. It doesn't work to define two or more top level criteria with AND/OR conditions. This is reproduced across all ADF versions.

Wizard allows to create two or more criteria groups:

However, when you run the page - ADF Query renders search item only from the second criteria group:

If you go to the source code of VO, XML contains indeed only one criteria group, this is why only one was rendered on UI:

Switch to wizard mode and open the same View Criteria again - it still shows two criteria groups defined:

It looks like JDeveloper is caching criteria definition in memory, but really wizard is not able to construct proper XML and it is loosing one of the criteria groups.

Try to close and open same VO, open View Criteria wizard again - after closing/opening VO it will display only one criteria group (second group is lost):