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

Friday, June 17, 2011

ORABPEL-30017: Initialization Error

Product: Oracle SOA/BPM
Version: 11.1.1.4
OS: Windows 7

I deployed successfully to the SOA Server, however when I open BPM I get an initialization error.

To fix this error, go to your database, login as XX_SOAINFRA(where XX is the prefix that you specified during the installation of the SOAINFRA schema using the RCU utility) and run the following SQL:

select processId, processName, domainName, compositeName, revision, scaLabel, compositeDN, label, processType,
targetNamespace, status, organizationalUnitId, subType from BPM_CUBE_PROCESS.


and update the status to -1 for all entries.

Wednesday, March 30, 2011

JDeveloper 11g - ADF Workshop for Developers: Video & Photo Content Part 2

Finally I managed to find some time and upload some video and photo content from an event that Oracle Cyprus conducted back in October.

Tuesday, March 1, 2011

WSM-06102 The policy referenced by URI "policy name" could not be retrieved.

javax.xml.ws.WebServiceException: javax.xml.rpc.JAXRPCException: oracle.wsm.common.sdk.WSMException: WSM-06102
The policy referenced by URI "policy name" could not be retrieved.

If you get a Web Services Management error about missing policies, then most probably you haven't included the "Oracle WSM Policy Manager" product during the creation of your WebLogic domain.

To solve this, just extend your domain using the Configuration Wizard and include add the "Oracle WSM Policy Manager" product to your domain.

Wednesday, February 2, 2011

Web Services Interoperability between Oracle WebLogic Server 11g and Microsoft.NET WCF 4.0

Recently I was asked to demonstrate the interoperability in a real life scenario between Oracle WebLogic Server 11g and Microsoft.NET Windows Communication Foundation 4.0 using secure web services.

After a bit of research, I have found this very helpful article by Juan Carlos.

I will try to extend the above article and provide full step by step instructions on how to create a secure web service, deploy it on your integrated WebLogic Server and use Microsoft.NET WCF 4.0 and C# to consume it.

So let's start with developing the web service.


1. In the Applications Navigator, click New Application. Give your application a name (for example HelloWorldApp) and select Generic Application from the application templates. Click next.


2. Specify a project name (for example HelloWorldPrj) and click finish.


3. Create a new Java class in the newly created project by specifying a class name (HelloWorld), a package name (demo) and uncheck "Constructors from Superclass" and "Implement Abstract Methods" and click OK.


4. Copy and paste the following code below in your HelloWorld class.

public String sayHello(String name){
return "Hello " + name;
}


5. Once you have done this, click save all and right-click the HelloWorld.java class. From the menu, select "Create Web Service ...".


6. Select "Java EE 1.5, with support for JAX-WS Annotations" for the deployment platform and click next.


7. In the "Generation Options" step leave the defaults and click next.


8. In step 4 of the wizard, select SOAP 1.2 Binding and click next.


9. In steps 5 and 6 click next. In step 7, "Configure Policies", select "OWSM Policies" and "oracle/wss_username_token_service_policy" check box in the security policies and click finish.


10. Right-click the HelloWorld.java class and choose run. By doing so, the integrated WebLogic Server will start and the HelloWorld web service will be deployed to the server.


11. If you have followed my naming suggestions for the project and class name, you should see in the log window of the WebLogic Server a target url, http://localhost:7101/HelloWorldApp-HelloWorldPrj-context-root/HelloWorldSoap12. This is the actual web service url and JDeveloper provides you with a web service test client utility. Click on the link to test the web service.


12. In the HTTP Analyzer window, specify an input value. Make sure that you expand SOAP Headers, WS-Security:Header and check the include check box. In the username and password specify weblogic and weblogic1 respectively. If you do not include the security header, then you will get "InvalidSecurity : error in processing the WS-Security security header". Click Send Request.


13. You should see the reply back from the web service that we have developed and deployed on our WebLogic Server.


14. Before proceeding with creating a client to consume the web service, please copy the wsdl url (http://localhost:7101/HelloWorldApp-HelloWorldPrj-context-root/HelloWorldSoap12HttpPort?WSDL), as we will need it to create the proxy class from Visual Studio.


15. For creating the proxy class from our wsdl file, we will beusing the ServiceModel Metadata Utitlity Tool, called scvutil.exe.The ServiceModel Metadata Utility tool is used to generate service model code from metadata documents and metadata documents from service model code. So navigate to "C:\Program Files\Microsoft SDKs\Windows" and you should see one or more version folders. Open the latest folder (in my case i only have one, v7.0A) and then bin (the complete path is "C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin") and copy the path.


16. Right-click "Computer" and select "Properties". Click "Advanced System Settings" and select the "Advanced" tab. Then click "Environment variables".


17. Under "System variables", select the "Path" variable. Go to the end of the variable value and after including a semicolon (;), paste the ServiceModel Metadata Utility tool full path (C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin)


18. Click "OK" on the "Edit System Variable", "Environment Variables" and "System Properties" to save and dismiss all three windows. Open a command prompt and navigate to your desired location (in my case I have created a folder called demo on my desktop). Write the following command, "svcutil , to create the proxy class from the wsdl file. Please note to replace the with your wsdl url location. In my case it is "http://localhost:7101/HelloWorldApp-HelloWorldPrj-context-root/HelloWorldSoap12HttpPort?WSDL". If you run this command as it is, it will create a C# proxy class for the web service specified in the wsdl and a configuration file. if you want to generate the class in another language, svcutil provides you with a parameter called "language" where you can specify the language code to be generated (for example, you can append after the url location /language:VB to generate the class in visual basic).


19. The svcutil utility will generate two files, HelloWorldService.cs which is the C# proxy class and the output.config file, which is the configuration file. If you see warnings about policy assertions not being imported, don't worry, we will handle the security headers later.


20. Open Microsoft Visual Studio and create a new project.


21. From the Installed Templates, expand Visual C# and select Windows.Select Console Application, give your project a name (for example, HelloWorldVS) and click Ok.


22. Before proceeding and importing the two files generated (HelloWorldService.cs and output.config), we need to add to our project references to two assemblies for our solution to work. So right-click References and click "Add Reference".


23. From the "Add Reference" window, select the .NET tab and select "System.Runtime.Serialization" and "System.Service.Model" and click OK.


24. Next, right-click your project name (HelloWorldVS) and select Add -> Existing Item from the menu.


25. Navigate to the folder where your proxy and configuration file is (generated by svcutil) and make sure that the file filter is set to "All files (*.*)" so that both files (HelloWorldService.cs and output.config) are visible. Select both files and click "Add".


26. You should see the two files now in your project. Open the Program.cs file and in the main method, copy and paste the following code:

HelloWorldClient client = new HelloWorldClient();
String response = client.sayHello("Antonis Antoniou");
Console.WriteLine(response);


27. If you attempt to run the application (F5), you should see "Could not find default endpoint element that references contract 'HelloWorld' in the ServiceModel client configuration section.". This is because it is missing an application configuration file. Although we have imported the configuration file generated by svcutil, it is not recognized.


28. A simple trick to overcome this issue is to rename the output.config file to app.config. So if you rename the configuraiton file to app.config and run the application, the above error should disappear. However, a new error arises, "The CustomBinding on the ServiceEndpoint with contract 'HelloWorld' lacks a TransportBindingElement. Every binding must have at least one binding element that derives from TransportBindingElement.".


29. What this basically means is that because in our configuration file, a custom binding is specified, we need to define a transport protocol (for example, http, https). To do so, open the app.config file and just after the closing textMessageEncoding element, add the following:


30. If you run the application again, the TransportBindingElement error should be resolved. However now we have a new error, "InvalidSecurity : error in processing the WS-Security security header". As the error indicates, a security header is expected by our HelloWorld web service and we have not provided one.


31. The easiest way to provide this security header along with the username and password required to run the web service is again though the app.config configuration file. So open the app.config file and within the endpoint element add the security headers xml tags as shown in the image below.


32. Run the application again (Ctrl + F5). You should see the return statement from the HelloWorld web service

Download: JDeveloper Application
Download: Visual Studio Application

Monday, January 31, 2011

JDeveloper 11g - ADF Workshop for Developers: Video & Photo Content

Following a recent workshop conducted in Cyprus, I have uploaded some video and photo content from the event.