Pages

Friday, October 28, 2011

Playing with ADF Task Flows in OEPE 11.1.1.8


Oracle released the Oracle Enterprise Pack for Eclipse 11g R1 (11.1.1.8, New October 2011 ) which supports ADF Rich Faces with ADF Task Flow development. To see all the new features you can go this page for all the ADF or Oracle Cloud feature list.

In this blogpost I will show you some steps how to make your own ADF Web application in OEPE.

Before you can start you should know that the ADF application in OEPE uses JPA as model ( eclipselink), ADF BC can be used but only on runtime and you should already have WebLogic PS3 or higher installed ( together the ADF runtime option).

This OEPE release does not have ADF wizard for ADF BC or for ADF Datacontrols but the support for ADF Task Flows is a big step forward.

Let's start.
Start with a new Oracle ADF Application

Add a new WebLogic runtime, define your WebLogic home and run the domain wizard to create a new ADF enabled domain. Make sure you add the JRF option to the domain.


You should use JPA as a model project with Oracle ADF 11g JPA Project as the configuration.



This will create 2 projects, Model and AdfGuiWeb and 1 ear deployment called AdfGui.


Create a JSP File which will be our start page.


Select the location for the JSPX page

Choose for ADF Rich Faces Page , Basic xhtml

Open the adfc-config.xml and drag the jspx page to the diagram, this will create a new view.


Create a new ADF Fragment Task Flow which will hold the department fragments


Select the location.

The fragment option should be enabled.


Create a new JSP page which will be our fragment page, called department.jsff


Now choose ADF Rich Faces Page Fragment

Open the departments TF and drag this fragment to this Bounded Task Flow.



Now we can go the model project and delete the model project. OEPE does not support ADF Datacontrol generation, so we will skip this for the demo.

Now you are able to run the JSPX page. Select the startView.jspx and right click Run As -> Run on server.

After a successful run we can add an outputtext to the page and the fragment


Now drag the department Task Flow to the jspx start page and select Region. This will create the ADF binding pagedef file.



We can open the pagedef file and add your own bindings.



Or open the Data Palette window which shows you the available bindings



At last open the project options to enable the adf.oracle.domain.webapp shared libraries


Now you can run the start page with the Bounded Task Flow fragment.


As an extra you can also add some data to the page by fixing the Model project.
First add a database connection to the model project
Add JPA entitities from tables
Add a connection to the persistence.xml

Add Data Model Components to the Model project. This will create a managed bean for the JSF page and an EJB Session bean for the entities

EJB Session Bean


JSF bean


the managed bean code

The Data Pallette, drag and drop the FindAll method to the fragment page


And the result.

Sunday, October 23, 2011

Using FMW IdentityStore for your User management

In Fusion Middleware you can use IdentityStore framework to do all your user, role and password management. This IDM and JPS frameworks will give you a lot options which you don't have with the standaard JAAS framework of WebLogic ( you need to create your authentication provider and add a private principal to the subject).  IDM framework works really great with LDAP identity providers like the default WebLogic internal LDAP, OpenLDAP, Oracle Internet Directory ( OID ) or Microsoft Active Directory.
With this you don't need to make your own software to do some user management on a particular LDAP provider, IDM can do it for you and IDM will detect the right LDAP provider. So you just need to implement this and IDM will do all the work.

This is what you can do with IDM.
  • Retrieving and changing LDAP attributes of a user.
  • User management, search, create users in a particular LDAP provider.
  • Role management, search, create etc.
  • Retrieve a username and password from the credential store and use it in your own application.  
I will try to explain the different use cases in this blogpost.

Before we begin, is good to know how the IdentityStore will work with LDAP providers. Default it only works with the internal WebLogic LDAP. If you also want to use AD or OID, then you need to add it to WebLogic authentication provider of the myrealm security realm ( no need to add it to the jps-config.xml located at domain/config/fmwconfig ,this is only necessary when you don't use WebLogic ).
The jps serviceInstance called idstore.ldap can detect all the LDAP providers which are configured in WebLogic.
But when you have more then one LDAP providers then you got two options.
  • Add the virtualize property with value true to the idstore.ldap serviceInstance ( in jps-config.xml located at domain/config/fmwconfig ) . This will switch IDM from WebLogic to Oracle Virtual Directory mode. This will make sure that FMW applications will see all the users and roles. When you use Webcenter or SOA Suite / BPM Human worklist application then you need to add this property when you have more then one LDAP provider. In this OVD mode you can't retrieve the LDAP attributes of a user, OVD did not implement this option. 
  • Re-order the LDAP authentication providers. The first authenticator provider will be used and the other will be ignored, ( WebLogic will still use all it's authenticators for JAAS but FMW will not  ).  That's why in some forums or blogposts talk about re-ordering of the authentications providers. In most cases is setting the virtualize a better approach.  
Let's start with retrieving all the things we know about a user. Here I will retrieve its roles and all the LDAP attributes. ( this will not work with virtualize property on true and only on the first authentication provider )
Using LDAP attributes can be very handy for retrieving particular information which you can use in your application, like location information else you need to create a lot of roles to achieve the same. You can retrieve for example the location attribute and pass this value to the database ( Use it in Virtual Private Database VPD what Larry said it is a false cloud feature :-) ) or use it to disable some region screens.


Here I need to create JpsContext and lookup the IdentityStore. After that I can lookup the User with its UserProfile and retrieve the LDAP attributes by retrieving the PropertySet.


Important to know that these user operations will use the account defined in the authentication provider, there is no check if your normal user should be able to do so. So test this for a possible abuse.


These are the steps to create a new Role in your LDAP repository. Lookup the RoloManager and use the createRole method.




We can also create a user and assign a role to this new user. In this case also need to provide a AD property called samaccountname. After that I can retrieve the UserManager and use the createUser method. Lookup the role and assign to this user.


The last part is about how you can store your passwords in a safe way on the WebLogic Server. Every environment can have its own passwords and this can be managed by your Administrators.


To store a password in the credential store you can use the following wlst script.


start wlst.cmd from oracle_common\common\bin not from the the weblogic server home

connect('weblogic','weblogic1','t3://localhost:7101')
createCred(map="JPS",key="AD_ldap",user="CN=Administrator,CN=Users,DC=alfa,DC=local",password="Welcome02" ,desc="Windows LDAP user")
exit()


To allow FMW to retrieve this password I need to give the authenticated role some permissions on this map.

Open the jazn-data.xml of your FMW application, lookup the authenticated role and add the following entries
oracle.security.jps.service.credstore.CredentialAccessPermission with read permission for context=SYSTEM,mapName=JPS,keyName=AD_ldap.

Somehow I also need to do this for mapName=j2ee-app#V2.0. The WebLogic will provide some logging to say what you are missing.

And here the code to retrieve it.


You can download my sample application at github https://github.com/biemond/jdev11g_examples/tree/master/ADFSecurity

Sunday, October 16, 2011

Working with the Human WorkList api and create your own WorkList application

In this blogpost I will explain what is possible with the IWorkflowServiceClient ( HumanTask java client )  so you can integrate this in your own Custom WorkList application.  This way you don't need to use the standard BPM worklist application, add some extra functionality and also don't need to create HumanTask ADF Task Flow and deploy this to the SOA Suite server.

This demo shows you the power of Fusion Middleware where you can combine SOA Suite workflow to your own ADF applications.

At the end of this blogpost I will show you the link for this demo application which also contains the BPEL to create the HumanTasks.

Here are some pics of the demo application. You will get an overview of the tasks assigned to the weblogic user ( normally this will be replaced by the user of the application ). The user can search on certain field, change the ordering and control the maximum rows.


And in combination with the ADF UIShell template of Oracle you can make a multi task handling application. Every task you click on will have its own Tab. Here you can also lookup the extra information which is necessary to the user so it can handle this task.



Time to go back to the code.

I will start with a BPEL which invokes a HumanTask and to make my life easy I will use the flexible text , date or url fields of the HumanTask for my own important data so I don't need to examine payload.
This way you can search on these fields and use it in your own task entity.



And map the payload fields to the flex fields in a Assign activity. These fields are located in the systemMessageAttributes element.


Next is to retrieve these tasks from the java / ejb client. Todo so I need two libraries bpm-infra.jar and bpm-services.jar. Copy these jars from the soa server so you don't get serial id versioning errors.

I will use on behalf of so I don't need to have the password of the user and I can do all the actions of behalf of this user.

Start with a property file or you can set some java parameters

soa.properties
soaserver=soaps3.alfa.local:8001
humantask.user=weblogic
humantask.password=weblogic1

or set these java parameters on the project
-Dhumantask.url
-Dhumantask.user
-Dhumantask.password

For the tasks I will connect to the HumanTask EJB and for the Identities I need to connect the Identity SOAP Service.


We need to have an IWorkflowContext which I can use for the query operation on the Task bean. I will first authenticate with the superuser and then on behalf of the user of my application.

In this query on the human task I can control which attributes I want to use in my application.

List<String> queryColumns = new ArrayList<String>(); queryColumns.add(TableConstants.WFTASK_TITLE_COLUMN.getName());

And if I want to have the payload or the comments, I need to do this.
List<ITaskQueryService.OptionalInfo> optionalInfo =
    new ArrayList<ITaskQueryService.OptionalInfo>(); optionalInfo.add(ITaskQueryService.OptionalInfo.COMMENTS); optionalInfo.add(ITaskQueryService.OptionalInfo.PAYLOAD);

Do ordering on the tasks.

Ordering taskOrdering = null;
if ( "PRIO".equalsIgnoreCase(orderBy) ) {
 taskOrdering = new Ordering(TableConstants.WFTASK_PRIORITY_COLUMN, true,false);
 taskOrdering.addClause(TableConstants.WFTASK_TASKNUMBER_COLUMN, true,false);
} else if ("ID".equalsIgnoreCase(orderBy) ) {
  taskOrdering = new Ordering(TableConstants.WFTASK_TASKNUMBER_COLUMN, false,true);
} else if ("ESC_DESC".equalsIgnoreCase(orderBy) ) {
  taskOrdering = new Ordering(TableConstants.WFTASK_EXPIRATIONDATE_COLUMN, false, false);
} else if ("ESC_ASC".equalsIgnoreCase(orderBy) ) {
  taskOrdering = new Ordering(TableConstants.WFTASK_EXPIRATIONDATE_COLUMN, true, false); }
}

It is also possible to do a search and add a fixed where condition. For this we need to have a Predicate where we can add the states we want to see.

List<String> correctStates = new ArrayList<String>(); correctStates.add(IWorkflowConstants.TASK_STATE_ALERTED); correctStates.add(IWorkflowConstants.TASK_STATE_ASSIGNED);

Predicate predicateBasic = new Predicate(
  TableConstants.WFTASK_STATE_COLUMN,
  Predicate.OP_IN,
  correctStates);

predicateBasic.addClause(Predicate.AND,
 TableConstants.WFTASK_STATE_COLUMN,
 Predicate.OP_NEQ,
 IWorkflowConstants.TASK_STATE_STALE);

This Predicate can be combined to an other Predicate with an other AND / OR and finally added to the queryTasks method of the workflowServiceClient.getTaskQueryService()


To make your life easier try to convert the tasks to your own entity  so you can use your own attributes instead of using text1 etc.

You can download, fork or improve the Demo application at github https://github.com/biemond/soa11g_examples/tree/master/HumanTaskListApp

Thursday, October 6, 2011

Calling an OWSM protected service with Axis2 and Rampart

In a previous blogpost I used Axis 1.4 in combination with WSS4J 1.5 and because Axis 1.4 is getting old so I tried the same with Axis 2 and Rampart which uses WSSJ. For all the security details like the username and how to generate certificates you can check see my previous post.

Just like the Axis 1.4 post I will call a OSB service which has an oracle/wss10_username_token_with_message_protection_service_policy OWSM server policy.

Before we start we need to download axis2 and the matching Rampart version, I use in this blogpost the 1.60 versions of axis2 and Rampart.  Copy the Rampart jars to the axis lib folder and the Rampart modules to the axis2 modules folder.

Download the WSDL with it's XSDs from the Web Service.

After that use this ANT build file to generate a ADB web service proxy client. The wsdl I used has the Customer.wsdl as name.
This OWSM policy have different signing and encryption options on the message of the request / response. So we need to move the right WS security policies / assertions from the Customer WSDL to a Request and Response policy file.

Here is the Request Policy which matches with the oracle/wss10_username_token_with_message_protection_service_policy Server policy. I also added the Rampart Configuration which contains references to the keystore and the username I used. Add the sp:AsymmetricBinding, sp:SignedSupportingTokens and the sp:SignedParts & sp:EncryptedParts of the request from the customer wsdl to this policy file.
We also need to do this for the Response. Add the sp:AsymmetricBinding and the sp:SignedParts & sp:EncryptedParts of the response from the customer wsdl to this policy file.
Because we are using a keystore and a username token ( which got passwords ) we need to add a Password Callback class.
And here the test client which loads the Axis2 configuration with the Addressing and Rampart modules and also loads the Request and Response policy.
Here you can download my code at https://github.com/biemond/soa11g_examples/tree/master/OWSM_AXIS