Pages

Sunday, January 27, 2013

Active Directory user management with the IdentityStore framework of FMW

With the IdentityStore framework of Fusion Middleware you can change or create any user or role in almost every LDAP server. With this framework the authenticated user change their own password from ADF or in your own ADF Admin page you can create an user with its roles without knowing LDAP or know what LDAP server is used.

IdentityStore framework will automatically detect the configured WebLogic LDAP servers. Default is the internal WebLogic LDAP and this is also the first authenticator. You can also add other LDAP servers like Microsoft Active Directory or Oracle Internet Directory. For this you need to set the virtualize property with true as value to the idstore.ldap serviceInstance entry.
In this case I will set the AD Authenticator as first authenticator and don't use virtualize property, this way I can retrieve all the LDAP attributes and know for sure that new users are created in AD and not in the local WebLogic LDAP.

To create an user or change a password in AD we need to use LDAPS ( port 636 and not 389 ).  Else you will get this error javax.naming.OperationNotSupportedException: [LDAP: error code 53 - 00002077: SvcErr: DSID-03190E49, problem 5003 (WILL_NOT_PERFORM), data 0 ];

This means we need to configure SSL.

The first step is to import the AD ca key and the AD public key to the local WebLogic TrustStore keystore.


keytool.exe -importcert -trustcacerts -alias ad_ca -file C:\2008-ca.cer -keystore C:\oracle\JDEV11~1.6\WLSERV~1.3\server\lib\DemoTrust.jks -storepass DemoTrustKeyStorePassPhrase

Trust this certificate? [no]: yes

keytool.exe -importcert -trustcacerts -alias ad_pub -file C:\2008-pub.cer -keystore C:\oracle\JDEV11~1.6\WLSERV~1.3\server\lib\DemoTrust.jks -storepass DemoTrustKeyStorePassPhrase

We also need to set the Hostname verification to None.



Create the AD Authenticator and also put all Control Flag to Sufficient ( also the default Authenticator )


We need to use LDAPS so use 636 as Port and enable SSL


Restart the Weblogic server and check if you can see all the AD users and the AD roles in the WebLogic Console .


Here is the java code to change the password of the AD user




Here is the code to create an AD User with a password, add an AD role to this user and set the UserAccountControl to 66048.



Here you can download the demo application at github



Monday, November 19, 2012

JPA SQL and Fetching tuning ( EclipseLink )

When you use JPA in your project and your model project contains many entities with some Eager fetching relation attributes then you probably notice that EclipseLink can fire a lot of SQL queries on the database. This works ok & fast on Dev or Test but in production these queries can lead to big problems ( higher load and more data).
In our project we also use ADF DataControls, Web Services or Entity Transient attributes which does not support Lazy loading. So we need to tune this entities fetching.

In this blogpost I will use the department and employee entity of the HR Oracle demo schema to explain the JPA options you have to control the SQL statements and the JPA relation Fetching.


These two entities has the following relations
  • Department has a Manager
  • Department has Employees
  • Employee belongs to a Department
  • Employee has a Manager
  • Manager has Employees
First step is to set or leave all OneToMany relations to Lazy Fetching ( this is the default ). If you put everything on Eager then you will create an loop and EclipseLink will detect this and will throw an error.
If we only set the Department entity relations to Eager then the department named queries will be Ok but we can't retrieve everything from the Employee entity.   

But when you want to retrieve a Department with its Employees and Manager or a Manager with its Employees and Department plus you want to tune the fired SQL queries then you got the following options.


Here you see all the Department Named Queries.

Departments.findByName
select o from Departments o where o.departmentName = :name" 

this query will get all the Departments with a particular name and it retrieves all the ManyToOne relations like the department Manager. But this does not retrieve the Employees of the Department.


Departments.findByNameFetch
select o from Departments o left join fetch o.employeesList where o.departmentName = :name
If we want to fetch all the Employees of this department we can use join fetch. Fetch with join is necessary if you want to do Eager fetching. Also left join fetch ( outer join )  is necessary if you also want to query Departments without Employees. Plus this will do it in one SQL query.

Departments.findByNameFetch2
select o from Departments o where o.departmentName = :name
hints= { @QueryHint( name =QueryHints.LEFT_FETCH, value="Departments.employeesList") }
We can do the same with EclipseLink and use @QueryHint( name =QueryHints.LEFT_FETCH
This does the same as Departments.findByNameFetch , you can also use QueryHints.FETCH but this won't do an outer join.

You can also do the same on the Query, like this
em.createNamedQuery("Departments.findByName")
.setParameter("name", "Finance")
.setHint(QueryHints.LEFT_FETCH, "Departments.employeesList")
.getResultList();

Departments.findByNameFetch3
select o from Departments o where o.departmentName = :name
hints= { @QueryHint( name =QueryHints.LEFT_FETCH, value="Departments.employeesList.manager") }
EclipseLink can even do more than the standard JPA JQL query, in this example it can also retrieve the manager of the employees in the same SQL query instead of using separate queries ( this is not possible with normal JPA).

To see the all the executed SQL statements put the EclipseLink Logging to the Fine level.
This is the test client I used to test these queries
Here you can download or see all the code of my test project on github.

Tuesday, October 30, 2012

Easy way to access JPA with REST (JSON / XML)

With the release of EclipseLink 2.4, JPA persistence units can be accessed using REST with JSON or XML formatted messages. The 2.4 version supports JPA-RS which is a RESTful API for dealing with JPA. In this blogpost I will show you what is possible with JPA-RS, how easy it is and howto setup your own EclipseLink REST service. This is also possible when you want to expose database tables as SOAP Web Service, for more information on this topic see my blog about Eclipselink DBWS.

To test these REST Services I added the Dev HTTP Client extension to my Google Chrome browser.  Here you can download my testcases which I used in this blogpost and it is possible to import these in the Dev HTTP Client extension.

It is very important with every invocation to set the Accept HTTP Header property with application/json or application/xml as value, else you will get an error and EclipseLink won't know the requested response format.

We can start with HTTP GET and http://localhost:8080/HR-JPA-RS/persistence/ as url , This will show you all the JPA persistence units.  persistence is the mapping of the JPA-RS Servlet ( it's a web-fragment in the JPA-RS eclipselink jar ) and HR-JPA-RS is the context url of my GlassFish web application.


Now we know the Persistence Units we can ask for all the Entities of this particular HRLocal Persistence Unit. Use http://localhost:8080/HR-JPA-RS/persistence/HRLocal/metadata
This gives us the Department, Location and Employee entities of the Oracle HR Demo schema.


Next step is to retrieve the metadata of the Departments Entity. Here you can see all the entity attributes and relationships to the other entities, the supported Rest operations plus the Named Queries you can call.
http://localhost:8080/HR-JPA-RS/persistence/HRLocal/metadata/entity/Departments



We can call for example the findAll namedquery http://localhost:8080/HR-JPA-RS/persistence/HRLocal/query/Departments.findAll , a particular record http://localhost:8080/HR-JPA-RS/persistence/HRLocal/entity/Departments/190 or localhost:8080/HR-JPA-RS/persistence/HRLocal/query/Departments.findById;departmentId=200



To retrieve the manager of this department we can add manager to this url.  http://localhost:8080/HR-JPA-RS/persistence/HRLocal/entity/Departments/190/manager


When we want XML as response instead of JSON we can set the Accept HTTP Header to application/xml




Click here for more information what is possible with JPA-RS

Next step of this blogpost is about howto setup this eclipselink environment. For this I used OEPE ( Oracle Eclipse ) as IDE and GlassFish 3.12 as J2EE server. ( You can also use WebLogic 12c )

First we need to update the EclipseLink version of GlassFish to at least version 2.4.1. See this Oracle blogpost how to replace the current version of eclipselink . Also had to add org.eclipse.persistence.jpa.jpql.jar to this module folder.

This is my workspace overview. It contains a JPA and Web project and off course the EAR project.

In the web project I added the org.eclipse.persistence.jpars_2.4.xxx.jar to the lib folder of the WEB-INF.
The meta-inf folder inside this jar contains the web-fragment xml and this will automatically added to your web.xml ( if its support version 3.0 of the web-app )

The last step is to set the Persistence Units to Local Resource instead of JTA Datasource, else it won't work.

Here you can download the eclipse projects.