Showing posts with label Integration. Show all posts
Showing posts with label Integration. Show all posts

Tuesday, December 5, 2017

JET Composite Component in ADF Faces UI - Deep Integration

Oracle JET team doesn't recommend or support integrating JET into ADF Faces. This post is based on my own research and doesn't reflect best practices recommended by Oracle. If you want to try the same - do it on your own risk. 

All this said, I still think finding ways of further JET integration into ADF Faces is important. Next step would be to implement editable grid JET based component and integrate it into ADF to improve fast user data entry experience.

Today post focus is around read-only JET composite component integration into ADF Faces. I would recommend to read my previous posts on similar topic, today I'm using methods described in these posts:

1. JET Composite Component - JET 4.1.0 Composite - List Item Action and Defferred Loading

2. JET and ADF integration - Improved JET Rendering in ADF

You can access source code for ADF and JET Composite Component application in my GitHub repository - jetadfcomposite.

Let's start from UI. I have implemented ADF application with regions. One of the regions contains JET Composite. There is ADF Query which sends result into JET Composite. There is integration between JET Composite and ADF - when link is clicked in JET Composite - ADF form is refreshed and it displays current row corresponding to selected item in JET Composite. List on the left is rendered from series of JET components, component implements one list item:


As you can see, there are two type calls:

1. ADF Query sends result and JET Composite. ADF -> JET call
2. JET Composite is forcing ADF form to display row data for selected item. JET -> ADF call

Very important to mention - JET Composite is getting data directly from ADF Bindings, there is no REST layer here. This simplifies JET implementation in ADF Faces significantly.

What is the advantage of using JET Composite in ADF Faces? Answer - improved client side performance. For example, this component allows to expand item. Such action in pure ADF Faces component would produce request to the server. While in JET it happens on the client, since processing is done in JS:


There is no call to the server made when item is expanded:


Out of the box - JET Composite works well with ADF Faces geometry. In this example, JET Composite is located inside ADF Panel Splitter. When Panel Splitter is resized, JET Composite UI is nicely resized too, since it is out of the box responsive. Another advantage of using JET Composite in ADF Faces UI:


When link "Open" is clicked in JET Composite - JS call is made and through ADF Server Listener we update current row in ADF to corresponding data. This shows how we can send events from JET Composite to ADF Faces:


It works to navigate to another region:


And come back - JET content is displayed fine even after ADF Faces PPR was executed (simple trick is required for this to work, see below). If we explore page source, we will see that each JET Composite element is stamped in HTML within ADF Faces HTML structure:


Great thing is - JET Composite which runs in JET, doesnt require any changes to run in ADF Faces. In my example, I only added hidden ID field value to JET Composite, to be able to pass it to ADF to set current row later:


I should give couple of hints regarding infrastructure. It is not convenient to copy JET Composite code directly into ADF application. More convenient is to wrap JET code into JAR and attach it this way to ADF. To achieve that, I would recommend to create empty Web project in JDEV, copy JET Composite code there (into public_html folder) and build JAR out of it:


Put all JET content into JAR:


If Web project is located within main ADF app, make sure to use Working Sets and filter it out to avoid it to be included into EAR during build process:


Now you can add JAR with JET into ADF app:


In order for JET HTML/JS resources to be accessible from JAR file, make sure to add required config into main ADF application web.xml file. Add ADF resources servlet, if it is not added already:


Add servlet mapping, this will allow to load content from ADF JAR library:


To load such resources as JSON, CSS, etc. from ADF JAR, add ADF library filter and list all extensions to be loaded from JAR:


Add FORWARD and REQUEST dispatcher filter mapping for ADF library filter from above:


As I mentioned above, JET Composite is rendered directly with ADF Bindings data, without calling any REST service. This simplifies JET Composite implementation in ADF Faces. It is simply rendered through ADF Faces iterator. JET Composite properties are assigned with ADF Faces EL expressions to get data from ADF Bindings:


JET is not compatible with ADF PPR request/response. If JET content is included into ADF PPR response - context gets corrupted and is not displayed anymore. To overcome this we are re-drawing JET context, if it was included into PPR response. This doesn't reload JET modules, but simply re-draws UI. In my example, ADF Query sends PPR request to the area where JET Composite renders result. I have overridden query listener:


Other methods, where PPR is generated for JET Composite - tab switch and More link, which loads more results. All these actions are overridden to call methods in the bean:


Method reDrawJet is invoked, which calls simple utility method to invoke JS function which actually re-draws JET UI:


JET UI re-draw happens in JS function, which cleans Knockout.JS nodes and reapplies current JET model bindings:


JET -> ADF call is made through JET Composite event. This event is assigned with JS function implemented in ADF Faces context. This allows to call JS located in ADF Faces, without changing JET Composite code. I'm using regular ADF server listener to initiate JS -> server side call:


ADF server listener is attached to generic button in ADF Faces:


ADF server listener does it job and applies received key to set current row in ADF. Which automatically triggers ADF form to display correct data:

Tuesday, September 27, 2016

BPM Worklist API 12.2.1.1 and Custom ADF 12.2.1.1 Application

I have updated my sample app with BPM API usage in ADF application to 12.2.1.1. Originally this was developed with ADF/BPM 11.1.1.7 - Dynamic ADF Buttons Solution for Oracle BPM Outcomes. There are several changes in BPM libraries usage. I will describe it all step by step.

Download sample application - adfbpm12211.zip. This archive contains both BPM and ADF app. BPM process implements two roles - request holiday and approve holiday:


Main goal of such use case - we don't want to use out of the box Oracle Worklist app, but prefer to develop our own business logic and manage BPM process from custom ADF app through BPM API. It is important to initialize Workflow context one time during login, this can be heavy operation and we should not call it each time when BPM API is invoked:


I'm using authenticateOnBehalfOf method. This allows to use admin user as a proxy for business user connection. Once Workflow context is established, we can get BPM context to use it for BPM API calls, all this is done during login into ADF app:


Assigned tasks are fetched through Workflow context:


We can initiate new task through BPM API in our custom ADF app:


There is a way to generate buttons to control task actions dynamically. Buttons can be generated on top of task outcomes list obtained from BPM API:


Task action can be executed with payload info, this allows to pass correct info to the next step in the process:


Let's see how it works. User can start new BPM task from ADF:


When task is submitted to approval, manager is assigned task to approve or reject holiday request. Buttons are generated dynamically based on task outcomes:


To double check executed flow from BPM API in ADF we can review it in EM control:


ADF application must import BPM API JARs to be able to compile Java code. In ADF 12.2.1.1 it is enough to import BPM Services JARs:


There is no need to package these JARs into application archive, these should be referenced for compile time only:

Friday, March 6, 2015

Invoking REST Service from Oracle ACM Java Activity

In this post I will show you, how to call REST service from ACM Java activity class method. This could be useful in the situations, when you would like to have programmatic ACM activity integrated with REST service data. We could access ACM payload data from within the method overriden in the class implementing Case Activity Callback.

ACM activity implemented on top of Java class, contains the same properties and configuration as the regular one. You could define input/output data, execution properties, etc.:


Here is the Java code to invoke REST service from the Java class implementing ACM activity. I'm giving an example to parse ACM payload and access Last Name attribute. REST service is invoked through a library packaged with FMW 12c:


One important hint - you must place ACM activity class under SOA/src path (by default it goes into SOA/SCA-INF/src). This will ensure class will be compiled and executable on runtime:


REST Client library is referenced from FMW 12c installation, no need to add any external libraries:


Sample application implements Cancel Hotel Booking activity, the one which is based on Java class. It executes and calls a method:


Here is the output - Last Name printed out from the payload and REST service call result:


Here you can download sample application, this contains both REST service and ACM examples - HotelBookingProcessing_v2.zip. REST service application implementation - ADF BC Range Paging and REST Pagination. ACM application implementation - Adaptive Case Management 12c and ADF Human Tasks.

Saturday, January 10, 2015

How To Start a Case in Oracle Adaptive Case Management 12c

Blog reader was asking to describe how to start a new case in Oracle ACM 12c. You can read my previous blog post on ACM 12c topic - Adaptive Case Management 12c and ADF Human Tasks. There are multiple ways to start a case, depends if you want just to test the case or really use it. I would recommend to use SoapUI to test the case. In the real scenario, case most likely will be started from third party web service or through ACM 12c Java API. Here I would like to describe, how you could use SoapUI to test ACM process during development.

Once ACM 12c application is deployed, you could open it in EM. There is the option to test deployed composite and invoke it through EM Web Service tester. In the example below you can see startCase operation selected and payload structure displayed. Unfortunately it doesn't work well to test ACM process through EM, payload structure is very confusing and it usually fails with mandatory attributes missing errors:


Instead I would recommend to use SoapUI to test the ACM 12c composite. You could download and use it free of charge. Start the tool and choose to create New SOAP Project:


We need WSDL URL to define a SOAP project in SoapUI. You can copy WSDL URL from EM test screen:


Paste it into SoapUI dialog (Initial WSDL field) and Project Name will be filled in automatically (keep Create sample requests for all operations? option selected):


SoapUI will fetch all operations from the service and new SoapUI project will be generated:


In order to start a new case, expand startCase operation and open Request 1. Request will be pre-filled with default payload structure (similar as we saw in EM):


Save SoapUI project, before doing any changes to the request structure. I would suggest to save it under ACM JDEV application structure - project is saved into single XML file:


Change the request to include custom data payload (you can find this XML code inside sample application available for download) and invoke the service. If request will be successful, you should see case number returned in the response:


Case with the same number should be available in BPM Workspace:


Here you can download sample application with SoapUI project (XML file) included - HotelBookingProcessing_v1.zip.