Tuesday, April 28, 2015

WebSocket Integration with ADF for PPR Request Monitoring

WebSocket is a protocol enabling communication over TCP connection. Communication is interactive, meaning data can be sent both ways - from the server to the Web client and back. Data is sent through WebSocket channel, without using using regular HTTP. This means we can enable communication between server and Web client without consuming bandwidth from HTTP. WebLogic 12c is shipped with required libraries for WebSocket support, we can use this protocol straight away in ADF 12c. WebSocket supports JSON format, this allows to send and receive JSON formatted data, just the same as REST. In this post I'm going to describe how WebSocket could be used, to report PPR request time measured on the Web client (Monitoring PPR Request Time on ADF UI Client Side), back to the server.

JDeveloper 12c allows to create WebSocket project, this can be done in the existing ADF Fusion Web application:

Required libraries are not added automatically, developer needs to add them manually. If you are going to compile sample application for this post - make sure to set correct path for JSON library, otherwise project will fail compilation:

Below you can see example of server side WebSocket code. Class is annotated with ServerEndpoint path and contains various methods to listen for WebSocket events. One of the methods - processMessage with annotation OnMessage, this method is invoked when message from the Web client is received. I'm just printing out PPR request time measured on the client and sent through WebSocket channel:

WebSocket is using JSON format for the data message. Data structure must be defined by the POJO class:

In order to be able to use this structure with WebSocket, helper classes for encoding and decoding must be defined. Here is the example for encoder, it converts data structure to JSON String:

Decoder converts data back from JSON String to the data structure defined by POJO class:

Encoder/decoder is defined in WebSocket class annotation:

Let's see what is required to be implemented on the Web client side. Here we have simple Java Script code, where WebSocket connection is established - connection between Web client (browser) and server:

WebSocket connection is opened on main page load, by invoking Java Script method from clientListener:

Java Script function responsible for monitoring, sends measured PPR request time back to the server through WebSocket connection. See details in the sample application developed for this post:

This is how it works on runtime - user invokes PPR request, by pressing a button:

Server receives a message with information about PPR request time measured on the client. This message is received through the WebSocket, without using any bandwidth from HTTP channel. See printed message below:

Make sure to compile WebSocket project, before you run sample application.

Download sample application here - ADFAltaApp_v4.zip.

Friday, April 17, 2015

Monitoring PPR Request Time on ADF UI Client Side

We can measure how long it takes to process request on the server side, however it is equally important to measure how long PPR request takes on the client side. Mainly because this will be a key factor for application performance exposed to the end user. There is relatively easy approach in JSF 2.0 to measure PPR request time on client side - with a special ajax tag. ADF 11g R2 and ADF 12c are based on JSF 2.0, this means we can use such tag and measure request performance. Read in my previous post how to monitor page load time in ADF UI client - Monitoring Page Load Time on ADF UI Client Side.

Here is the example of ajax tag. It provides special property called onevent, this property points to custom JavaScript method, which will be invoked by the framework when PPR request starts and ends:

Ajax tag can be used for various ADF UI components, initiating request. Below you can see example of ADF Faces button configured with onevent monitoring, it points to custom JavaScript monitor method:

JavaScript monitor method is invoked automatically, when request starts and succeeds. This means we can get start and end time, calculate total time taken to process PPR request from click to rendered response:

I would like to emphasise importance of this approach, based on example of ADF TF opening. Task Flow is a server side concept, on runtime its all is converted to HTML and rendered in the browser. When user clicks on the button, to render ADF TF content, he waits until it is initialised on the server side, business logic is executed and finally response is rendered. My example contains Method Call activity with delay code intentionally, to demonstrate how PPR request time measurement works:

ExecuteDelay method call invokes Java method, where thread is paused for 5 seconds:

Let's see how it works on runtime. Home page contains a list of employees, there is team hierarchy link available for each employee. On user click, it loads ADF TF with Hierarchy viewer (ADF TF explained above, with thread delay):

PPR request time starts when user clicks on the link and ends when ADF TF UI fragment content is rendered. This gets close to 6 seconds (there is added 5 seconds delay time from TF method call). We can measure, how long it really takes to see the content for the user, starting from the first click:

As soon as PPR request is completed, Hierarchy viewer component renders team structure:

Navigation back to the list is measured as well, it takes below 1 second:

PPR requests time for Save/Cancel/Back buttons in edit screen is measured in the same way:

Download sample application with implementation of described approach - ADFAltaApp_v3.zip.

Wednesday, April 15, 2015

Monitoring Page Load Time on ADF UI Client Side

In certain situations, it might be useful to monitor ADF page load time. This is pretty easy to achieve with Navigation Timing API and Java Script. Navigation Timing API is supported by modern browsers and allows to retrieve client side load time. It takes into account data transfer time and actual rendering in the browser - real time it took for a user to see the content.

We could use ADF clientListener operation with load type, to identify when ADF UI is loaded. This listener should be added to the ADF UI document tag and it will be invoked at the end of page rendering. Through clientListener, we could invoke our custom JavaScript method, where we could calculate page load time on ADF UI client side:

The most important thing here, is to get page load start time. This value is retrieved from Navigation Timing API (mentioned above) - performance.timing.navigationStart. The rest is easy - we can get load time:

This is how it looks like on runtime. When I recompile ADF application and redeploy it on the server, first load is obviously slower. ADF UI is rendered on the client side (starting from page load request) in 10 seconds (look at top right corner):

Second access is a way faster - page load on the client side happens in 1 second:

You can test it yourself, download sample application (redsam/welcome1) - ADFAltaApp_v2.zip.

Wednesday, April 8, 2015

Simple (Effective) Refresh Approach for ADF Regions

I often hear developer asking about how to refresh different regions on the same page, when specific event happens in one of the regions - to refresh dependent regions. Usually developers would like to use something more simple than Contextual Event approach. There is more simple approach, may be it doesn't work for all the possible use cases - but it does it job, when just refresh is needed. This approach is based on dummy parameter value, being used as dependent region input parameter, with refresh option set to be ifNeeded.

For the sample test case, I'm using ADF 12c application (SimpleReloadRegionApp.zip). This application contains two AM's, to simulate two Data Controls to be used in separate regions:

Fragment from the first region, generates refresh event, when Save button is pressed. For this purpose, I have registered Property Listener to update flag variable. This variable value is initialised from refreshToken method, available in RefreshHelperBean:

Bean method is very simple, it takes current timestamp value and returns it to String. This value always will be changed and this ensures dependent region refresh:

Make sure to set input parameter for the region TF you want to refresh, this should be simple parameter of type String:

TF must call Execute operation, this will force to reload VO rowset data, before loading the fragment:

In the main page, where region is consumed, change refresh condition to ifNeeded and set refreshFlag parameter to point to the variable initialized in the first region (by property listener):

There are two regions rendered on the UI. Once I change data in the top region (form component) and press Save, second region below is refresh automatically and it fetches latest available data from DB:

Friday, April 3, 2015

Indicator for Background REST Service Access with A-Team Mobile Persistence Accelerator

You should check my previous post about Background REST Service Access with A-Team Mobile Persistence Accelerator (AMPA). There I describe how to optimise MAF performance for REST service calls, allow user to continue working with the mobile application, without locking the screen until Web Service response arrives. Steven Davelaar have documented how it works, you can read it in his blog - Calling Web Services in Background Using MAF 2.1.

I have updated sample application from previous post, to include indicator for AMPA background service call status tracking. Updated sample application - MobileServiceBusApp_v8.zip.

AMPA provides application scope variable, which acts as a flag and indicates when background service call is executed. Based on this flag, we could conditionally display animated GIF image, this will help user to understand if background service call still runs:

When user is searching and request is being processed in background, he will see rotating status indicator in the top right corner:

Until data is being returned from background task, user could go to another screen and monitor when request is completed, to see the latest data:

Once background task completes, indicator disappears:

Sunday, March 29, 2015

Automatic ADF Popup Opening on Fragment Load

I had a post about opening ADF Popup on page load - Opening ADF PopUp on Page Load. Approach is quite straightforward, developer needs to use showPopupBehavior operation with appropriate trigger type. When it comes to ADF Popup opening on fragment load, implementation is a bit more complex. There is a known method to implement hidden text field and in the getter method call your custom logic - getter will be executed when fragment loads. However, this is not very efficient, you will need to add condition to distinguish between first and subsequent calls to the getter (it will be executed multiple times). I will describe in this post different approach - using ADF poll component and forcing it to execute only once after fragment load.

Here you can download sample application - FragmentPopUpLoadApp.zip. This sample implements two UI tabs. Each of the tabs renders ADF region. First region displays information about all employees - tree map with salary information:

Automatic popup opening is implemented in the second region - Employees By Department tab. As soon as user opens this tab, popup is load to select department. Data in the region is filtered, based on department selected in the popup:

Filtered data after selection was made in automatically opened popup:

Popup in the fragment is loaded on the first load by ADF poll component. Poll component is set with short interval of 10 milliseconds. During its first execution it will call Java listener method and in addition JavaScript client listener will be invoked. Inside JavaScript client listener, we disable ADF poll component by setting its interval to be negative. This is how ADF poll executes only once and then it stops:

Here is Java listener method, invoked by ADF poll component - it loads the popup:

ADF poll is stopped after its first execution. However, we need to ensure it will be started again - if user re-opens the same tab. For this purpose I have implemented conditional ADF region activation - region is de-activated when user navigates away from the tab. Tab disclosure listener updates helper variable to track which tab becomes active:

Disclosure listener updates page flow scope variable - forceActivate:

This variable is used in the region definition - region is active when tab is selected, and inactive otherwise:

Sunday, March 22, 2015

Background REST Service Access with A-Team Mobile Persistence Accelerator

REST service transfers light data, but service execution time could bring significant delay to the enterprise mobile application. I have already introduced you to the A-Team Mobile Persistence Accelerator (AMPA) in previous post - REST Service Access with A-Team Mobile Persistence Accelerator. Based on AMPA author - Steven Davelaar suggestions, I will post today updated application, where REST service call will be handled in background. This will allow mobile user to continue working with the MAF application, while REST call is being processed in background thread.

Here you can download updated sample application - MobileServiceBusApp_v7.zip. Remote read in background is configurable through AMPA persistence mapping, I have changed it to be false - let's see how it works for slow REST service execution:

Data Control method is executing (sequential in this example) remote findAll operation through AMPA, to fetch employees data. Data collection is loaded to the UI, after service execution is completed:

Server side ADF BC VO is set to wait 30 seconds (waiting for 30 seconds after VO was executed), before completing SOAP response. This allows to simulate slow REST service execution and check how MAF mobile application behaves with sequential service call:

Executing search operation over slow REST operation blocks entire MAF mobile application. User can't navigate to other screens and is locked into current screen, until response comes. This is how it looks like, when I changed search criteria - mobile application waits for the response:

Obviously this is inappropriate, because it blocks application and user can't continue his work. Let's test with AMPA configured to execute REST calls in background - remoteReadInBackground = true:

Data Control method responsible to execute REST action is refactored. I'm only starting remote findAll operation - not waiting it to complete. AMPA generated service class EmployeeService is changed to include additional constructor, where I'm passing instance of Data Control class and a flag to prevent auto query. Here is applyFilter method from Data Control class, it call REST service in background, through AMPA:

AMPA generated class is changed with overriden method refreshEntityList. This method is called automatically by AMPA, when background REST call is completed. Here I'm calling Data Control class method, responsible to refresh UI and display data fetched from the background service:

Data Control class method responsible for UI refresh - it updates Data Control collection and invokes synch with UI:

I will describe a test I have completed, with REST service execution in background. Perform search action with a parameter:

ADF BC on server side executes VO with SQL statement, there is a wait time of 30 seconds:

MAF mobile application is not blocked anymore, as it was with sequential REST service execution. User can navigate to other screen and do different actions:

Once ADF BC VO completes execution and SOAP service returns response, Service Bus is transforming SOAP response to REST. Mobile application receives data and UI refresh happens, to present latest changes. User can view the changes, once he is back to the screen:

In the same way, user could run another search:

While search is running, user could view details for present data:

After returning back to the search list, results for the new search query are displayed - data from REST service call executed in background:

User could load details screen and view the data: