Skip navigation.

Andrejus Baranovski

Syndicate content
Blog about Oracle technology
Updated: 14 hours 13 min ago

Oracle Process Cloud Application Player

Tue, 2015-07-21 10:12
With Oracle Process Cloud you can forget these days when you was waiting long to deploy BPM process and test Human Task UI. No need to wait anymore, in Oracle Process Cloud you could use Application Player feature, this allows to run the process and test Human Task UI almost instantly.

To demonstrate Application Player functionality, I have implemented basic process of Data Entry for the Claim Handling:


This process is using Web Form in the Start activity to capture data, human activity Claim Expense Review allows to review entered data, before submitting it:


This is how Web Form UI design looks like:


When you build Web Form and arrange UI components, business type is constructed automatically, no need to define anything separately. Business type can be used in the process, without changing it:


Data object variable is assigned to the process activity element through Association dialog in Process Cloud, this is where you can map input/output with business type:


Once process is ready to be tested, all you need to do is to invoke Application Player. Click on Test Application button in the top right corner:


In the Test Application window you should select Play option:


To show how it works, I have recorded a video - see yourself how helpful is Application Player:

Auto Refresh for ADF BC Cached LOV

Thu, 2015-07-16 08:19
You can configure auto refresh for ADF BC cached LOV and this works out of the box, no special coding is needed. My previous post describes how ADF BC session cached LOV behaves - ADF BC Session Cached LOV - Understanding Expire Time. Auto refresh can be configured for both application and session caching. One important thing - auto refresh doesn't work when ADF BC is configured with disconnected mode (ADF BC Tuning with Do Connection Pooling and TXN Disconnect Level). I would guess this is related to DB notification listener, it can't notify about DB changes, when DB connection is being taken from AM.

Make sure to remember to configure AM without disconnected mode. Auto refresh works for both application and session caching levels:


As a reminder - in order to use shared LOV functionality, you must select VO instance for LOV from shared AM configuration. See how it looks in the LOV definition wizard:


Auto refresh functionality is enabled with a single property - AutoRefresh = true. This can be set through VO general properties or directly in the VO source code:


Make sure Disconnect Application Module Upon Release option is not set:


I have overriden VO method processChangeNotification for logging purposes, this method is invoked automatically for VO's set with AutoRefresh = true. No need to code anything here, I'm just logging method invocation:


Let's do a test. First of all, check entries of Job list:


Go to DB and update one of the entries. For example, change Stock Clerk title and commit changes:


Come back to UI and press any button. This will trigger new request and Jobs list shared VO will be notified about DB change to refresh:


Check the list again, you should see changed entry for Stock Clerk:


In the log we can observe a call for change notification, it triggers shared LOV query re-execution and data re-fetch:


See recorded demonstration video, where I show refresh behaviour live:


Download sample application - ADFBCSharedSessionLOVApp.zip.

ADF BC Session Cached LOV - Understanding Expire Time

Sat, 2015-07-11 10:11
ADF BC offers LOV caching feature. There are two caching levels - application and session. With application level enabled, it makes LOV rows available for all users. On contrary for session level LOVs, data is cached for single session only. In this post I will focus on session level LOV's and I'm going to explain when cached data expires and is re-fetched.

You can configure caching level for LOV's in Model.jpx file, open AppModules section and select appropriate caching level for AM. I will be using Session level. Key point to understand - session level caching for LOV is nothing to do with Web user session lifetime. Session here is AM session, and cache remains in memory only until AM session remains assigned to the current user session:


LOV with caching feature is defined a bit differently, List Data Source must be selected from shared AM, other steps are the same:


My sample application implements two different VO's, based on Employees data. Both VO's are using the same cached LOV in session level for Jobs. This helps to make a test and check if cached LOV data expires. When cache is not expired, LOV data cached during first VO initialisation, should be present on the second LOV access. Above is example of Jobs LOV definition for Employees VO and below another example of Jobs LOV definition for Employees By Departments VO:


LOV VO is created with implementation class, where I override createRowFromResultSet method. It helps to track if LOV data was expired and rows were re-fetched:


As I have mentioned earlier, there are two VO's, both using the same cached LOV. On UI I have two different fragments, each located in TF. Call between two TF's is implemented, I'm using two different TF's to simulate Isolated TF behaviour. Isolated TF creates new instance of AM and this clears the cache of LOV on AM session level:


Let's understand how it works. First fragment is loaded, LOV data is fetched and cache is populated:


We can observe in the log, all rows fetched for LOV:


Open second fragment, LOV data is not re-fetched, it will be taken from the cache:


There are no rows fetched reported in the log:


Session cache works correctly for LOV. Now if user invoked Rollback, AM is reset and this indicates end of cache on AM session level, rows will be re-fetched. Try to press Cancel button:


There will be entries in the log, showing information about fetched rows - cache was cleared on Rollback:


Let's do another test with second TF set with Isolated option. When TF is set to be Isolated, it will force new AM instance creation, each time with TF is loaded. Meaning - there will be always new AM session and LOV cache will never be reused. TF is set to be Isolated:


Try to open TF and check LOV:


Differently than before, LOV data will be fetched - new AM instance was created on Isolated TF access and this requires to refill LOV data list:


Download sample application - ADFBCSharedSessionLOVApp.zip.

Oracle Process Cloud Service - SOAP Web Service Integration

Tue, 2015-07-07 09:03
Oracle Process Cloud (https://cloud.oracle.com/process) allows to invoke SOAP services, along with REST services. You can define a library of SOAP services in Oracle Process Cloud application and use them within the process. This helps to integrate with business logic running on premise.

I have implemented regular SOAP service in ADF BC, just to test how it works to invoke it from Process Cloud:


SOAP service method accepts employee ID and checks the status. ADF BC application is deployed on standalone WLS. Make sure to select correct deployment profile, when deploying ADF BC with SOAP on standalone server, otherwise SOAP service reference will be missing in deployed application. You should use ADF BC service deployment profile:


Once SOAP service is deployed, you can access WSDL file through Enterprise Manager. Oracle Process Cloud currently doesn't support direct SOAP references, instead you must provide WSDL file copy for Web Service registration:


Download WSDL file from URL (here is the sample WSDL, I was using for my test - HrModuleService.wsdl). This is how it looks like, it contains SOAP service description:


Here you can see Oracle Process Cloud interface. It looks quite user friendly and functional, this is what I like about it. On the left side, there is menu with different objects - Processes, Web Forms, Web Services, etc.:


To add new SOAP service reference is fairly easy, provide a name and upload WSDL file:


Once service is registered, we can go to the process diagram and select Service component from the palette:


Drag and drop it on the diagram, Implementation section will be opened, where you should specify SOAP service reference to be invoked:


Select Service Call from the list, this allows to invoke SOAP Web Service:


Once option for Service Call will be selected, you will be able to select Web Service reference. I have defined only one service, it is listed in the popup - select it:


Operation field is listing all available methods from the service, select one of the operations to be invoked:


Data associations are available to define correct mapping for the input/output values for the SOAP Web Service call, this can be done through Process Cloud composer window:


If you are interested in Human Task UI implementation in Oracle Process Cloud, read my previous post about REST service integration: Oracle Process Cloud Service - Consuming ADF BC REST Service in Web Form.

Oracle Process Cloud Service - Consuming ADF BC REST Service in Web Form

Sat, 2015-07-04 08:57
With the introduction of Oracle Process Cloud Service (https://cloud.oracle.com/process) there is an option to run your business process in the cloud. You can implement very similar things as it is possible with BPM 12c in JDeveloper, but only in the cloud. There is no option to implement human task UI with ADF, it must be done with Web Forms (light UI forms implementation framework). This is disadvantage, as it will require to externalise complex business logic and access data collections through REST calls, instead of processing it locally in ADF extension. However, this is how it is implemented currently in the BPM cloud version.

This is how it looks - Web Form editor in Process Cloud Service:


You have an option to select specific types from component palette. There are such types as money, email, phone, text. Components are provided with built in validation, checks for valid email address, etc. User who implements a form, needs to drag and drop components one by one (generally it works OK, but sometimes may get stuck and page refresh will be required). Properties section is available to enter details for the selected component.

Cool part about it - we can define business logic rules. For example, to show/hide customer field based on trip type, etc. One of the rules below, shows how REST service can be called inline and REST response is applied for drop-down field. This is pretty simple to fetch data from external REST service and use it for the Web Form component. Just invoke REST service and assign collection to the component supporting array of data:


If REST call requires to pass parameters through URL, this is also possible, see example below - list of cities, based on the selected country in the Web Form:


Web Form works pretty well in Preview mode, it even calls REST services and shows real data. Validation messages for built-in checks are displayed pretty nicely. Here I'm selecting a country from the list populated by REST service:


Based on the selection in the Country drop-down, filtered list for Cities becomes available (another REST call):


Good news - most of the Oracle Process Cloud interface itself is implemented with ADF. Here you can see a section listing all Web Forms available for the current process:


I have implemented REST service for Countries and Cities lists in ADF BC. There are two custom methods in AM implementation, to fetch the data and transform it to the list format:


REST resources are defined through annotations and are configured to produce JSON data, this will allow Oracle Process Cloud to parse such data automatically:


If you are going to check how REST service is implemented in ADF BC, you can run a query in Postman to retrieve a list of all countries from HR schema:


Another query to retrieve a list of cities, by country:


Download sample application, with ADF BC REST service - RestADFBCApp.zip.

Intercepting Table Filter Query and Manipulating VO SQL Statement

Wed, 2015-06-24 13:30
I’m going to describe one non declarative use case. Imagine, if there is a table with filter functionality, you may want to intercept filter items and apply the same for another VO. This another VO should be based on the same DB table, so it could apply criteria items against the table.

Sample application - AdvancedViewCriteriaApp.zip, implements a fragment with table component and a chart. Table component can be filtered, criteria is intercepted and applied for the chart, this one is rendered from different VO with GROUP BY query. Chart stays in synch and displays data according to the criteria filtered in the table:


In the log, I’m printing out intercepted criteria from the table filter:


Chart is rendered from the SQL query below:


Table filter criteria is being intercepted by overridden method buildViewCriteriaClauses. Criteria clause is constructed here, we just need select FilterViewCriteria, the one originating from table filter. We could apply this criteria straight ahead to the VO responsible to bring chart data. However, this would not work - ADF BC would wrap original chart SQL query with SELECT * FROM (…) QRSLT WHERE (table filter criteria). This would not work, because table filter criteria is not present in the original chart SQL statement. To make it work, I’m updating original SQL query for chart data, by updating WHERE clause part:


In the last step, we need to pass bind variable values - the ones user is searching for in table filter. This can be done from another overridden method - bindParametersForCollection. We have access to the applied bind variables in this method. Again, you should check for FilterViewCriteria and extract applied bind variables values. Chart VO will be updated with bind variable definitions created on the fly and assigned with values to search for:


I hope this trick will save some of your time, if you are going to implement something similar - to intercept table filter query and apply it to the another VO, based on same DB table.

Select One Choice with Select Items Tag

Thu, 2015-06-18 08:26
If you need to implement select one choice based on alternative data sources (not based on ADF BC) - you shouldn't use af:forEach inside af:selectOneChoice component. Don't get confused with af:forEach tag, this tag is supposed to generate multiple components and not to iterate over a collection of objects and render HTML for each item. There could be cases, when choice list data will come duplicated, with af:forEach tag applied. I would suggest to construct array of SelectItem objects and return it to the f:selectItems tag to be rendered.

This is how proper af:selectOneChoice definition should look like. Array of items is being rendered in the choice list through f:selectItems tag:


Value property for f:selectItems can be entered manually or through the wizard, when creating af:selectOneChoice - this should point to the custom method, where array of SelectItem objects is constructed:


Custom method could read data from any source and construct array of SelectItem objects. This is the input for f:selectItems tag, it knows how to render a list of choice list items out of it:


This is how it looks on runtime - choice list is working fine, no need to use af:forEach:


Download sample application - CustomSelectListApp.zip.

How To Record ADF Client Side Request Performance Time

Thu, 2015-06-11 00:13
I had a blog post, where I have described how to monitor client side request performance time with Ajax tag (works in ADF 12c) - Monitoring PPR Request Time on ADF UI Client Side. There is effective way to propagate recorded statistics back to the server for history logging using WebSockets - WebSocket Integration with ADF for PPR Request Monitoring. This requires WebSockets integration into project, if project doesn't allow this - there is another way. We could leverage Ajax call to the Java servlet and pass logged statistics data through parameter. I will describe how this can be achieved.

Sample application - ADFAltaApp_v6.zip, implements standard servlet. In the doGet method, I'm accessing parameter and parsing received statistics data. From here we could log data to the DB, so it could be analysed further. Data processing should be executed in the separate thread, not to block servlet execution and return response back to the client. Java in ADF 12c supports asynchronous servlets, however this is not the case with ADF 11g versions (unless you change JVM to 1.7). Parameter processing in the servlet:


On the client side, JavaScript code contains a method to acquire Ajax XmlHttpRequest object. Through this object we can invoke servlet, directly from JavaScript:


In the monitor function (invoked automatically on start and end events for the request) - we are invoking servlet and passing request performance data to log. I'm executing synchronous call, this is done on purpose - asynchronous calls in JavaScript can be lost, if user executes requests fast, portion of the data will be skipped. Synchronous call is made at the end of the request and usually is pretty fast (make sure to log data in the separate servlet thread, not to block execution):


This is how it works. Press Save button - you will see information about request processing time embedded in the top of the page (this is calculated and updated in JavaScript function from above):


Servlet on the server side prints received data to be logged - button ID, request processing time, user info:


Try to invoke another request - navigate back to the previous fragment. Time will be logged and displayed in the top part of the page, same is communicated to the servlet for logging:


Time is being logged on the server side:


I hope described idea will be useful for your own project, where you could measure ADF UI client performance (from button click, until action is done). Ajax tag to catch request start and stop events works only in ADF 12c, but you could do similar thing in ADF 11g with custom JavaScript listeners.

How to Apply New Label Text in MDS Customisation

Thu, 2015-06-04 14:49
It may look simple, but really is not obvious how to apply new label text for the ADF BC attribute or UI component through MDS customisation. It is simple, if such label text already exists in the core bundle. If you need to create new label text in the customisation and use it - this becomes a bit tricky. Well, as usual - I'm going to explain how you could solve such task. You should read more about MDS customisation setup in ADF - MDS Seeded Customization Approach with Empty External Project.

Core application - mds_label_cust.zip, contains one label for First Name VO attribute:


The requirement is to customise core application and add label for the Last Name VO attribute, without changing anything in the core. For this purpose, we need to create different JDEV application - extension, configured with shared library deployment profile. Here you could simply create new properties file. We are going to use this application to deliver additional components for the core. Keep in mind - core application must be configured to use this library. Add label for Last Name VO attribute, in the properties file located in the extension:


Time for the main trick. We could use label directly from any resource bundle in the ADF application. This is accomplished through such expression - reference for the resource bundle and label key:


This code should be part of customisation project, on runtime it will find referenced resource bundle and label key in the resource bundle from extension (see above).

This is how it looks on runtime - label text is taken from resource bundle in extension and applied by customisation:


It sounds more tricky, than it is - just try it.

Load More Scroll Policy for ADF 12c Table and Range Paging

Fri, 2015-05-29 13:19
There is a new scroll policy for the table component in ADF 12c. This new policy is called - load more. I think it gives good potential, it allows to reduce access load on heavy tables. In ADF 11g we are implementing similar approach with RowCountThreshold = -1 setting, this is preventing full scroll at once (How To Disable SELECT COUNT Execution for ADF Table Rendering). Load more is better, it integrates with VO Range Paging and allows to configure maximum number of rows present on the client.

New scroll policy is configurable directly on the ADF UI table component, as a property:


Load more works based on configured Range Size for the iterator in the bindings. In my example, I have set it to be 15, this means there will batches of new rows added in the groups of 15 elements:


One of the key things - new scroll policy works with VO Range Paging, this allows to fetch less rows from DB and improve ADF BC runtime performance:


There is no need to set Range Size, it will be calculated automatically, based on the current set of rows rendered in the table on runtime.

This is how it looks like on UI. User scrolls in the range and is given option to Show More rows. Total number of rows is also visible:


What is good about Load more scroll policy, it doesn't keep all fetched rows. If user want to come back to the first set of rows, he will be given Show More rows option in the top of range - to display previous set of rows:


Below you can see SQL query executed to fetch rows in the current range. This query is based on Range Paging feature and contains range variables:


If I would navigate back in the range and display previous 15 rows:


New SQL query is executed with Range Paging, with different range variables:


What is good about it - SQL query range paging variables are calculated automatically, there is no need to implement any custom logic to keep them in synch.

One extra feature to be described - blockNavigationOnError (also available in ADF 11g). This could be useful feature, if you want to prevent selecting rows in the table, when there is validation error in the current row:


Row selection is blocked, until validation error will be fixed:


Download sample application - ADFTableLoadApp.zip.

Responsive UI Support in ADF 12.1.3

Thu, 2015-05-28 10:26
Responsive UI is a big deal nowadays, when enterprise applications should run on different platforms and devices. Often customers prefer to render simpler functionality screens for mobile devices and give full data entry access only when accessing through regular Web browser on the computer. ADF provides support for this, you can implement responsive UI designs relatively easy, check informative blog post from Shay Shmeltzer - ADF Faces Responsive Design - 12.1.3 Update.

I would suggest to think about responsive UI design from the start, it very much depends on functionality your application offers. It is good idea to start from the template and define facets for various layouts. But this is not only about layouts, you may prefer to render editable forms on large screens and on mobile devices to show only charts for quick overview. I'm going to demonstrate, how you could switch between different regions in ADF UI, depending on current resolution. Download sample application here - ADFResponsiveUIApp.zip.

This is how it works, I'm using iPad simulator, but same would be true for the regular browser display on smaller screen resolutions. Web page displays region with editable columns in horizontal view and same page displays different region with read-only list in vertical view:


Similar to Shay's sample, there is a template implemented with two facets (each for different layout):


Facet visibility is managed through assigned style class, controlled by CSS media query. It checks if screen width is less than 950px and sets narrow layout to be displayed:


Main page is created based on the template. Here I'm inserting both regions into corresponding facets - wide and narrow:


This is editable table in wide view:


This is read-only list in narrow view:

ADF 11.1.1.9 Goodies - Conveyor Belt Component and Alta UI

Sat, 2015-05-23 09:59
It doesn't seem to be announced, but newly released ADF 11.1.1.9 is shipped with Alta UI support. All you need to do, is to set alta skin name in trinidad config file. This enables applications running on ADF 11g platform to leverage new Oracle UI layout and to be prepared for ADF 12c upgrade. Besides Alta UI, there are several new UI components, one of them is Scrollable Bar (ConveyorBelt) - Displaying Components in a Scrollable Bar. This is simple, but quite useful component - I'm going to demonstrate how it works.

Conveyor Belt is able to render elements horizontally or vertically. This is perfect component to render key information, user could select one of the items available on the belt and get more info fetched. This is how it looks like - conveyor of employee pictures with first/last names, rendered in the vertical belt on the left:


If there are more items in the conveyor belt, than could fit into visible UI part - user could scroll (right/left and down/up). Here I scroll down and select another employee, his detail data is displayed in the main section:


As you could notice, UI is displayed using Alta skin. This is configured in trinidad file:


Here is the structure for implemented conveyor belt, items in the conveyor are stamped dynamically through ADF UI iterator component. Java Script client/server listeners are responsible to process item selection and keep detail info in synch for the selected employee:


This is the source code structure for conveyor belt UI implementation, based on the structure from above:


Conveyor item selection is processed in the server listener method, VO current row is set based on the selected key:


If you want to try it yourself, download sample application - ConveyorBeltApp.zip.

ADF and Two-Way WebSocket Communication Architecture

Sat, 2015-05-16 05:02
This post is based on WebSockets and ADF, topic described in the previous post - WebSocket Integration with ADF for PPR Request Monitoring. I would like to look into it from technical architecture perspective and split WebSockets server logic into separate application deployed on WebLogic. WebSocket is two-way (bidirectional) communication channel, this allows to send and received data at the same time. I'm going to demonstrate how it works with my sample application.

It is best to explain how WebSocket works, with a live demo - you can watch recorded screencast. I'm using Twitter stream, you should see how many tweets are coming in for music category. Each tweet location is sent through WebSocket channel to ADF page, where it is rendered on the UI, through Java Script. ADF UI performance is measured in Java Script and logged back to the server through the same WebSocket channel. Tweet locations are coming from the server to ADF UI and ADF UI performance statistics traveling back to the server, at the same time:


I'm pretty amazed, how WebSocket transfers data - you should see how quick output text value is changing in ADF UI.

Download sample application - ADFAltaApp_v5.zip. Below diagram describes the main idea of this example:


There are two applications deployed on WebLogic 12c server. WebSocket server side application is listening for Twitter stream and sends data to the WebSocket client running in ADF UI. Logged performance data in ADF UI is sent back to WebSocket server side application.

Twitter stream handler is implemented as a servlet. It listens for every tweet received for the given topic and invokes WebSocket method to send data to the client:


Data is sent to the client using WebSocket API (library is available out of the box in WebLogic 12c and JDeveloper 12c). Incoming message is handled by another method - processMessage. This method accepts complex type, sent from ADF UI in JSON format:


Make sure to define WAR deployment profile for WebSocket project, this must be deployed as part of EAR. There should be deployment profile set, later referenced from WebSocket client:


WebSocket client runs in Java Script, there is onMessage function to handle incoming data. Here I'm simply setting newly received text as value for the ADF output text component:


ADF output text is empty initially, value is populated on runtime through WebSocket:


WebSocket communication from ADF UI to WebSocket server side is initiated in Java Script. PPR request timing data is written to JSON format and sent over WebSocket channel:

WebSocket Accelerated Live Data Synchronization for MAF

Mon, 2015-05-11 02:42
New generation Mobile and Web applications are going to use WebSockets. This is one of the fastest and convenient ways to transfer JSON formatted data from the server to the client and back. Huge advantage - server could initiate data synchronisation request and deliver JSON messages directly to the client. You should read my previous post about detail information how to configure MAF with WebSocket - Oracle MAF and WebSockets Integration - Live Twitter Stream.

In this post I would like to describe, how to integrate further information received through WebSocket with MAF components. I will use MAF Tree Map UI component to display live data for Tweets locations.

Below you could see screen recording - MAF Tree Map is getting refreshed automatically, each time when update through WebSocket channel is being received. This is amazing, how fast data through WebSocket channel is coming. In this test, MAF is handling around 1 update per second, received from WebSocket:


Let's look how it is implement behind the scenes. There is MAF Tree Map UI component, this is regular MAF component to render graph visualisation:


UI component is based on Data Bindings, collection is initialized from Data Control method:


Method handling data update from WebSocket is responsible to update data collection - it invokes helper method, where data collection is re-constructed. Standard Refresh Provider is helping to repaint data displayed on the UI:


Simple and effective. Download sample application - AltaMobileApp_v2.zip.

Oracle MAF and WebSockets Integration - Live Twitter Stream

Wed, 2015-05-06 23:26
Oracle MAF and WebSockets - I will describe how it works together. WebSockets is a protocol providing full-duplex communication channel over a TCP connection. This channel is interactive (communication is both ways) and we can send messages from the server to the client (MAF application running on the device). There is no need to use push notifications, WebSockets provide JSON support and allow to send complex payload data. In a way it competes with REST, however REST is different with request is being initiated by the client. WebSockets data is received automatically - there is no need to trigger any event by the client.

I have implemented sample MAF application with WebSockets integration, you can download it here - AltaMobileApp_v1.zip. Finance screen in the application contains MAF output text component. This component displays latest data received through WebSockets channel. Server side is listening for live Twitter Stream updates and sends each tweet location over WebSockets to the MAF application. See how it works in this screen recording:


WebSockets communication is not blocking MAF application functionality, it runs in the separate thread. User can navigating between MAF screens, run different actions and WebSockets delivers data in parallel.

Sample applications is based on two parts - server side WebSockets implementation with Twitter Stream listener and client side MAF application with WebSockets client.

Twitter Stream is handled with Twitter4J API, JAR's are included with the sample. You would need to provide your own Twitter account details, access keys could be retrieved for your account from Twitter developer portal. Make sure to obtain these keys, before running sample application:


New message from Twitter Stream is received by listener method - onStatus. I'm listening for all the tweets around the world, related to corporate keyword. Once there will be new tweet related to this topic, onStatus listener will be notified. In the listener method, I'm retrieving tweet location and and initiating WebSockets communication:


Method in WebSockets implementation - notifyClient, sends text message to the client (JSON message is supported as well):


Listener for Twitter Stream is started automatically, when application is deployed. This is done through servlet initialisation:


On the client side - MAF application is configured to receive automatic notifications through WebSockets channel. Implementation for WebSockets listener is very similar with the regular ADF Faces - it is done through JavaScript. MAF feature is registered with JavaScript file:


JavaScript contains all required methods for WebSockets communication. Here we open WebSockets channel with connectSocket function and further listen for the new messages/notifications with onMessage method. My goal is to update MAF components with the new data received through WebSockets. For this reason, I'm invoking Java method from onMessage JavaScript function and passing payload data (recently received tweet location):


Invoked Java method - processWebSocketMessage is responsible to update MAF bindings with the new data. Data Bindings class contains standard MAF propertyListener implementation, which ensures data refresh on MAF UI:


MAF output text on the UI displays recent data received through WebSockets channel:

SOA & BPM Partner Community Webcast May 8th 16:00 CET

Wed, 2015-04-29 12:49
Save the date for the Webcast below - make sure to attend, if you don't want to miss SOA & BPM news.
SOA & BPM Partner Community Webcast May 8th 16:00 CETJoin us for our monthly SOA & BPM Partner Community Webcast. We will give you an update on our SOA Suite 12c, Integration Cloud Service offerings and our community activities.


Speakers:
Vikas Anand
Jürgen Kress

Schedule: May 8th 2014 16:00-16:45 CET (Berlin time)

Attendance Information:
Join Webcast or dial in Call ID: 4070776 and Call Passcode: 333111
Austria: +43 (0) 192 865 12
Belgium: +32 (0) 240 105 28
Denmark: +45 327 292 22
Finland: +358 (0) 923 193 923
France: +33 (0) 15760 2222
Germany: +49 (0) 692 222 161 06
Ireland: +353 (0) 124 756 50
Italy: +39 (0) 236 008 198
Netherlands: +31 (0) 207 143 543
Spain: +34 914 143 755
Sweden: +46 (0) 856 619 465
Switzerland: +41 (0) 445 804 003
UK: +44 (0) 208 118 1001
United States: 140 877 440 73
More Local Numbers Watch and listen
You can join the Conference by clicking on the link: Join Webcast  (audio will play over your computer speakers or headset). Visit our SOA Partner Community Technology Webcast series here.

WebSocket Integration with ADF for PPR Request Monitoring

Tue, 2015-04-28 10:28
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.

Monitoring PPR Request Time on ADF UI Client Side

Fri, 2015-04-17 12:55
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.

Monitoring Page Load Time on ADF UI Client Side

Wed, 2015-04-15 03:26
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.

Simple (Effective) Refresh Approach for ADF Regions

Wed, 2015-04-08 12:56
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: