Monday, November 28, 2011

IWorkflowServiceClient Interface changes in 11gPS4 (get authenticated user from BPM)

A recent upgrade from 11gPS3 (11.1.1.4) to 11gPS4 (11.1.1.5) has revealed some changes in the IWorkflowServiceClient interface (oracle.bpel.services.workflow.query package) which provides you with a programmatic means for retrieving tasks, task details etc.

More specifically, we where using the Workflow Services API to get the authenticated username from BPM and propagate it to our custom ADF application which was embedded inside a Human Task as a region.

String contextStr = ADFWorklistBeanUtil.getWorklistContextId();
IWorkflowServiceClient wfSvcClient = WorkflowService.getWorkflowServiceClient();
ITaskQueryService queryService = wfSvcClient.getTaskQueryService();
IWorkflowContext wfContext = queryService.getWorkflowContext(contextStr);
String userId = wfContext.getUser();


Please note that in 11gPS4, to retrieve the IWorkflowServiceClient object, you need to use the TaskFlowPropsUtil interface and NOT the WorkflowService interface, and pass to the getWorkflowServiceClient method the lookup client object which can be retrieved using the ADFWorklistBeanUtil interface.

String contextStr = ADFWorklistBeanUtil.getWorklistContextId();
String lookupClient = ADFWorklistBeanUtil.getLookupClient();
IWorkflowServiceClient wfSvcClient = TaskFlowPropsUtil.getWorkflowServiceClient(lookupClient);
ITaskQueryService queryService = wfSvcClient.getTaskQueryService();
IWorkflowContext wfContext = queryService.getWorkflowContext(contextStr);
String userId = wfContext.getUser();

Thursday, November 17, 2011

ADF Contextual Events

Oracle provides us with a very powerful feature to implement view-to-region, region-to-view, and region-to-region communication without requiring the region or the reference bounded task-flow to be refresh or restarted.

In this example, i will be showing you on how you can achieve region-to-region communication using the HR schema. I will create two task-flows, each consisting of a single JSF page fragment. The first JSF page fragment (named PageA.jsff) includes the employeess ADF form with some navigation controls and a submit button and the second JSF page fragment (names PageB.jsff) includes the employees ADF table.

I have created a third JSF page, demo.jspx, which will include the above stated pages as regions. I will use ADF Contextual Events to refresh the employees ADF table once a change has been made in an employee using the employee ADF form in the first page.

I have created a new application (named "ADFContextualEvents") with the "Fusion Web Application (ADF)" application template and using the "Business Components from Tables" i have created a connection to the HR schema, creating the Employees entity, a default view for the Employeess entity (EmployeesView) and an Application Module which includes the EmployeesView.


I created two task-flows, TaskFlowA and TaskFlowB. Both task-flows include a single JSF page fragment (TaskFlowA includes PageA and TaskFlowB includes PageB). The first page includes the Employees ADF Form
while the second page includes the employees ADF table.
I then created a normal jspx page (called demo.jspx) which includes the two task-flows created above as an ADF region. If you run the page and try to do a change in one of the employees, you will see that the changes are not reflected in the table below.
To refresh the view and subsequently the table to show the changes made in the form above, I will use Contextual Events. So the first thing that I will do is to create a method in the Application Module that will refresh (by re-executing) the view.
public void refreshEmployees(){
getEmployeesView().executeQuery();
}
Please make sure that you expose this new method to the UI using the client interface option of the Application Module.
You need to add this method in PageB’s bindings as a method action using the page definition file.
Next, you need to define when the event should be triggered. This should be every time the user clicks the “Submit” button that is included in PageA (where the ADF Form is).
Finally, in the page that includes both task-flows as regions (demo.jspx), we need to define the subscriber for the event that will be triggered with the Submit button. To do so, go the page definition and select the “Contextual Events” and then the “Subscibers” tab and click on the green plus icon “Add a New Subscription”.
In the “Subscribe to Contextual Event” window, select the event that you have created, the publisher of the event and the handler (in our case, it is the method that we have created in the Application Module and included it in the second page’s page definition as a method action, and click OK.
If you run the demo page that includes both task-flows as regions, you will see that by doing a change in one of the employees using the employee form, the employees table displays the new changes without needing to refresh the region or page.
Download: ADF Contextual Events

Friday, September 16, 2011

Propagate authenticated user from BPM to ADF using BPM API and ADF Task Flow parameters

In my previous post, I have demonstrated how you can propagate the authenticated user from BPM to your custom ADF Application using Contextual Events.

In this post, I will demonstrate how you can achieve the exact same result, this time using BPM API and ADF Task Flow parameters.

So, let’s first start with creating the custom ADF application. This will be a very simple application, where I will create a taskflow with a parameter and a fragment page to just display the taskflow parameter that will eventually hold the authenticated username that will get propagated from BPM.
I just created an ADF Application, named “DemoADF” and selected “Fusion Web Application (ADF)” from the Application Templates.
Next create an ADF TaskFlow and name it, DemoTF. Make Sure that the “Create with Page Fragments” checkbox is selected.
If not opened, open the DemoHT ADF Human Task that you have just created and using the overview view option, create a parameter, naming it “UserNameFromBPM”, setting the class to “java.lang.String” and the value to “#{pageFlowScope.UserNameFromBPM}”.
Create a new view component and name it “Demo”.
Double click to create the page fragment and drag an output label ADF component, setting the value attribute to “Authenticated User: #{pageFlowScope.UserNameFromBPM}”
Now, we need to package this ADF Application that we have just created into an ADF Jar Library. To do this, right-click the ViewController project, select new from the context menu and in the “New Gallery” window, select “Deployment Profiles“ from the Categories and “ADF Library JAR File” from the items and click OK.
In the “Create Deployment Profile” window, give your deployment profile a meaningfull name (for example, DemoADF, and click OK.
In the “Edit ADF Library JAR Deployment Profile Properties”, just click OK. The same with the “Project Properties” window, just click OK.
To deploy your ADF Application in the ADF JAR Library, you need to right-click the ViewController project and select Deploy > DemoADF
In the “Deploy DemoADF” window, click next and in the Summary screen, make sure to note down the location of the generated jar file (in my case, it’s C:\JDeveloper\mywork\myBlog\DemoADF\ViewController\deploy) and click Finish.
So, we are done with the custom ADF Application, now it’s time to create our SOA Application. So create a new application, name it DemoSOA and from the templates select “SOA Application”.
In the project name screen, you can give your project the same name as your application, that is DemoSOA.
In the “Configure SOA settings” screen, select “Composite with BPEL Process” from the Composite Template section and click Finish.
In the “Create BPEL Process” window, accept all defaults and click OK.
Create a Human Task by dragging the Human Task component form the Component Pallet onto the components swim lane. On the “Create Human Task” window, accept all defaults and click OK. Your composite application should resemble as the image below.
Edit the newly create Human Task and assign the “weblogic” user as the participant of this Human Task.
Edit the BPEL component and drag and drop a human component between the receive (receiveInput) and invoke(callbackClient) activity.
Edit the Human Task component that you have just dropped onto the BPEL Designer and in the “Task Definition” drop down, select “Humantask1” (it’s the human task that you have created in the composite application) and click OK.
Now it’s time to generate the human task form for the human task component. To do this, go to the composite.xml file, and double-click the human task component. From the human task editor, select Create Form > Auto-Generate Task Form.
In the “Create Project” window, give your project a name, such as DemoHT, and click OK.
JDeveloper will automatically create for you the ADF Human Task Form in the project that you have specified in the previous step. Once finished, it should display you with the auto-generated form.
So, now I want to include the Demo.jsff page fragment that I have create from the custom ADF Application in my human task form. How to do this? First, we need to create a File System Connection to the location of the generated ADF JAR Library. You can do this using the Resource Palette. In the “Create File System Connection” window, give your connection a name (for example, DemoADF) and the path to the generated ADF JAR Library. Click “Test Connection” to test your connection and then OK.
From the Resource Palette, expand the IDE Connection, File System and your file system connection name (in my case it’s DemoADF) and you should see the generated ADF JAR Library (DemoADF.jar).
To include and use the contents of this jar file in the human task project, make sure that you have selected from the application navigator the DemoHT project, and from the Resource Paletter, right-click the DemoADF.jar file and select from the context menu “Add to Project”.
In the “Confirm Add ADF Library” window, just click the Add Library button.
Oracle provides us with an API to get the authenticated BPM user from a human task (that is from the BPM context), using the IWorkflowServiceClient, ITaskQueryService queryService and IWorkflowContext wfContext interfaces.
So to use this API, we must create a java class with a simple method that will use this API and return the authenticated user as a string.
In the newly created java class, add the following method:

String userId = "";
try {
IWorkflowServiceClient wfSvcClient;
ITaskQueryService queryService;
IWorkflowContext wfContext;

String contextStr = ADFWorklistBeanUtil.getWorklistContextId();
wfSvcClient = WorkflowService.getWorkflowServiceClient();
queryService = wfSvcClient.getTaskQueryService();
wfContext = queryService.getWorkflowContext(contextStr);
userId = wfContext.getUser();

} catch (Exception e) {
e.printStackTrace();
}

return userId;

When prompted, please import the following packages:

import oracle.bpel.services.workflow.client.IWorkflowServiceClient;
import oracle.bpel.services.workflow.datacontrol.WorkflowService;
import oracle.bpel.services.workflow.query.ITaskQueryService;
import oracle.bpel.services.workflow.verification.IWorkflowContext;
import oracle.bpel.services.workflow.worklist.adf.ADFWorklistBeanUtil;
Using this newly created java class, create a data control by right-clicking the java class and selecting from the context menu “Create Data Control”.
Open the human task form (taskDetails1.jspx) and go the page bindings by using the “Bindings” tab. From the “Bindings and Executables” tab, click the green plus sign in the bindings section to create a new control binding.
In the “Insert Item” window, ensure that “Generic Bindings” is selected in the drop down menu and select “attributteValues” from the items and click “OK”.
In the “Create Attribute Binding” window, click the green plus sign to add a new data source.
In the “Add Data Source” window, expand SecurityUtils, Constructors, demoht.utils.SecurityUtils and select “SecurityUtils” and click “OK”.
Back in the “Create Attribute Binding” window, select “authenticatedUser” and click “OK”.
Switch back to design view and from the Component Palette, make sure that you have selected DemoADF.jar from the drop down menu.
Expand the Regions section and drag and drop the DemoTF region from into the panelGroupLayout component that is included into the Contents showDetailHeader component as an ADF Region (you might find it easier to user the structure window).
In the “Edit Task Flow Binding” window, set the value of “UserNameFromBPM” input parameter to the inputValue (if you followed my exact steps, then this would be “#{bindings.authenticatedUser.inputValue}”) of the attributeValue that we have created just above that represents the return value of the java method created earlier and click “OK”.
So now, we are ready to deploy and test if the authenticated user from the BPM workspace is propagated to the custom ADF application that was included in the Human Task form as an ADF region.

First, we need to deploy the DemoSOA project by right-clicking the project and selecting Deploy > DemoSOA
and then we need to deploy the human task form. Please note that you should deploy the project that contains the human task form (DemoHT) using the Application menu, Deploy > DemoHT and NOT by right-clicking the project and selecting deploy.
Once you have successfully deployed both, DemoSOA and DemoHT projects, please go to the Oracle Enterprise Manage (http://localhost:7001/em), locate the newly deployed SOA Composite Application (DemoSOA) and create a new instance by clicking on the test button.
Specify a value in the input field and click the “Test Web Service” button.
This will create a new instance of the DemoSOA composite application. If you remember, this composite consists of a BPEL and a Human Task Component. So it will initiate a bpel process and when it reaches the human task component, it will wait for a human intervention by the weblogic user.

So let’s login to the BPM workspace application (http://localhost:8001/bpm/workspace) to see all pending tasks.
Click on the DemoSOA task and wait for the human task form to load on the bottom half of the screen. The human task form should load and you should see the authenticated user, in this case weblogic, to get propagated from the BPM workspace to the custom ADF Application that we have developed earlier and included in the human task form as an ADF region.
Download: Propagate authenticated user from BPM to ADF using BPM API and ADF Task Flow parameters

Tuesday, August 30, 2011

Propagate the authenticated user from BPM to ADF using Contextual Events

A common issue that we are facing in nearly all implementations involving creating custom ADF Applications with Oracle Business Process Management Workspace Task Flows is getting the authenticated user (and setting history columns such as created by, created on, etc) from the BPM workspace application to the embedded, as regions, custom ADF Applications.

In normal ADF Applications, to get the authenticated user, using the “ADFContext.getCurrent().getSecurityContext().getUserName()” API will return you with the authenticated user. This is not the case if you created an ADF Application, zipped it into an ADF Library JAR File and used this ADF Application (and more specifically the different Page Flows) as ADF Regions in a Human Task Form.

The above mention method does not work (ADFContext.getCurrent().getSecurityContext().getUserName()) in remote ADF BC, always returning anonymous, as it is the intermediary user between the BPM and ADF Application.

Oracle provides us with an API to get the authenticated BPM user from a human task (that is from the BPM context), using the IWorkflowServiceClient, ITaskQueryService queryService and IWorkflowContext wfContext interfaces.

So the question now is how to pass the username from the BPM Human Task section to the ADF region? Well, of course using Oracle ADF Contextual Events.

So, let’s first start with creating the custom ADF application. This will be a very simple application, where I will create a simple java class with just one method. This method will have only one parameter and will return a string and will be used for handling the contextual event.
I just created an ADF Application, named “DemoADF” and selected “Fusion Web Application (ADF)” from the Application Templates.
Create a new java class in the Model project, specifying Demo as the class name and create a new method as follows:

public String getAuthenticatedUserFromBPM(String username){
     return "Hello " + username;
}
Once you created the getAuthenticatedUserFromBPM method, right-click the Demo.java class and from the context menu select “Create Data Control”. JDeveloper with automatically create for you a data control, exposing all public methods defined in the Demo.java POJO.
Now, create an ADF Task Flow in the ViewController project. Name it DemoTF and ensure that the “Create with Page Fragments” checkbox is selected.
From the components palette, drag and drop a view component onto the bounded task flow and name it Demo.
Double click the Demo view and create the demo fragment, accepting all defaults.
From the Data Controls section, expand the Demo data control and the getAuthenticatedUserFromBPM method and drag and drop the String return type on the Demo.jsff fragment as an input text with label.
On the “Edit Action Binding” window, just click the OK button. You can optionally change the label of the input text to something meaningful, for example “Authenticated User”. The page fragment should resemble as the image below.

Now, we need to package this ADF Application that we have just created into an ADF Jar Library. To do this, right-click the ViewController project, select new from the context menu and in the “New Gallery” window, select “Deployment Profiles“ from the Categories and “ADF Library JAR File” from the items and click OK.
In the “Create Deployment Profile” window, give your deployment profile a meaningfull name (for example, DemoADF, and click OK.
In the “Edit ADF Library JAR Deployment Profile Properties”, just click OK. The same with the “Project Properties” window, just click OK.
To deploy your ADF Application in the ADF JAR Library, you need to right-click the ViewController project and select Deploy > DemoADF

In the “Deploy DemoADF” window, click next and in the Summary screen, make sure to note down the location of the generated jar file (in my case, it’s C:\JDeveloper\mywork\myBlog\DemoADF\ViewController\deploy) and click Finish.
So, we are done with the custom ADF Application, now it’s time to create our SOA Application. So create a new application, name it DemoSOA and from the templates select “SOA Application”.
In the project name screen, you can give your project the same name as your application, that is DemoSOA.
In the “Configure SOA settings” screen, select “Composite with BPEL Process” from the Composite Template section and click Finish.
In the “Create BPEL Process” window, accept all defaults and click OK.
Create a Human Task by dragging the Human Task component form the Component Pallet onto the components swim lane. On the “Create Human Task” window, accept all defaults and click OK. Your composite application should resemble as the image below.
Edit the newly create Human Task and assign the “weblogic” user as the participant of this Human Task.
Edit the BPEL component and drag and drop a human component between the receive (receiveInput) and invoke(callbackClient) activity.
Edit the Human Task component that you have just dropped onto the BPEL Designer and in the “Task Definition” drop down, select “Humantask1” (it’s the human task that you have created in the composite application) and click OK.
Now it’s time to generate the human task form for the human task component. To do this, go to the composite.xml file, and double-click the human task component. From the human task editor, select Create Form > Auto-Generate Task Form.
In the “Create Project” window, give your project a name, such as DemoHT, and click OK.
JDeveloper will automatically create for you the ADF Human Task Form in the project that you have specified in the previous step. Once finished, it should display you with the auto-generated form.
So, now I want to include the Demo.jsff page fragment that I have create from the custom ADF Application in my human task form. How to do this? First, we need to create a File System Connection to the location of the generated ADF JAR Library. You can do this using the Resource Palette. In the “Create File System Connection” window, give your connection a name (for example, DemoADF) and the path to the generated ADF JAR Library. Click “Test Connection” to test your connection and then OK.
From the Resource Palette, expand the IDE Connection, File System and your file system connection name (in my case it’s DemoADF) and you should see the generated ADF JAR Library (DemoADF.jar).
To include and use the contents of this jar file in the human task project, make sure that you have selected from the application navigator the DemoHT project, and from the Resource Paletter, right-click the DemoADF.jar file and select from the context menu “Add to Project”.
In the “Confirm Add ADF Library” window, just click the Add Library button.
Open the Human Task Form (taskDetails.jspx) and from the Component Palette, make sure that you have selected DemoADF.jar from the drop down menu.

Expand the Regions section and drag and drop the DemoTF region from into the panelGroupLayout component that is included into the Contents showDetailHeader component as an ADF Region (you might find it easier to user the structure window).
In the same panelGroupLayout component, drag and drop a button component, above the ADF region. You can optionally change the button text (in my case, I changed it to Get Authenticated User).
We need to create an action for this button so that it will get the authenticated user. To do this, double click the “Get Authenticated User” button and create a new managed bean with a new method as in the image below and click OK.
Replace the contents of the getAuthenticatedUser method with the code below:

String userId = "";

try {

IWorkflowServiceClient wfSvcClient;
ITaskQueryService queryService;
IWorkflowContext wfContext;

// Get username of User Login
String contextStr = ADFWorklistBeanUtil.getWorklistContextId();
wfSvcClient = WorkflowService.getWorkflowServiceClient();
queryService = wfSvcClient.getTaskQueryService();
wfContext = queryService.getWorkflowContext(contextStr);
userId = wfContext.getUser();

} catch (Exception e) {
e.printStackTrace();
}

return userId;


When prompted, please import the following packages:

import oracle.bpel.services.workflow.client.IWorkflowServiceClient;
import oracle.bpel.services.workflow.datacontrol.WorkflowService;
import oracle.bpel.services.workflow.query.ITaskQueryService;
import oracle.bpel.services.workflow.verification.IWorkflowContext;
import oracle.bpel.services.workflow.worklist.adf.ADFWorklistBeanUtil;

Using the above specified method, we can get the authenticated BPM workspace user. Please note that this method ONLY works within the BPM context, that is from a human task form. To propagate the authenticated user returned by the method to the custom ADF Application that we have included onto the human task form, we will have to use ADF Contextual Events.

To do this, select the “Get Authenticated User” button and from the Property Inspector, expand the Behaviour category and click the green plus sign (Add a New Event Entry) in the Published Events section.
Specify GetAuthenticatedUserEvent as the event name in the “Publish Contextual Event” window and select the “Pass Custom Value from” check box.
From the drop down menu, next to the “Pass Custom Value from” check box, select “Managed Bean Method Return” and select the managed bean that you have created (DemoBean) and in the Properties drop down, the method that you have created for getting the authenticated user (authenticatedUser) and click OK.
So now the “Get Authenticated User” button will call the managed bean method that will return the authenticated user and will create an event.

We need to specify who will “listen” for these events created, that is we need to register the ADF region that we have created from the custom ADF Application as a subscriber of these events. To do this, make sure that the human task form is opened (taskDetails1.jspx) and click the bindings tab.
From the bindings page, select the “Contextual Events” tab and from the “Subscribers” tab, click the green plus icon (Add a New Subscription).

In the “Subscribe to Contextual Event” window, click the browse button next to the Event text box.
In the “Select Contextual Event” window, select the GetAuthenticatedUserEvent event and click OK.
From the Publisher drop down, select the taskDetails1PageDef.eventBinding entry and select the browser icon next to the Handler text box. From the “Select Handler” window, select the getAuthenticatedUserFromBPM handler (expand DemoTF1, DemoPageDef) and click OK.
Back in the “Subscribe to Contextual Event” window, ensure that the Parameters tab is selected and click the green plus icon.
In the name, specify outcome and in the value, specify #{payLoad} and click OK.
So now, we are ready to deploy and test if the authenticated user from the BPM workspace is propagated to the custom ADF application that was included in the Human Task form as an ADF region.

First, we need to deploy the DemoSOA project by right-clicking the project and selecting Deploy > DemoSOA
and then we need to deploy the human task form. Please note that you should deploy the project that contains the human task form (DemoHT) using the Application menu, Deploy > DemoHT and NOT by right-clicking the project and selecting deploy.
Once you have successfully deployed both, DemoSOA and DemoHT projects, please go to the Oracle Enterprise Manage (http://localhost:7001/em), locate the newly deployed SOA Composite Application (DemoSOA) and create a new instance by clicking on the test button.
Specify a value in the input field and click the “Test Web Service” button.
This will create a new instance of the DemoSOA composite application. If you remember, this composite consists of a BPEL and a Human Task Component. So it will initiate a bpel process and when it reaches the human task component, it will wait for a human intervention by the weblogic user.

So let’s login to the BPM workspace application (http://localhost:8001/bpm/workspace) to see all pending tasks.
Click on the DemoSOA task and wait for the human task form to load on the bottom half of the screen.

Click the “Get Authenticated User” button and, voila, you should see the authenticated user, in this case weblogic, to get propagated from the BPM workspace to the custom ADF Application that we have developed earlier and included in the human task form as an ADF region.
Download: Propagate the authenticated user from BPM to ADF using Contextual Events