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.

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 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.

Sunday, October 28, 2012

Using JSON-REST in ADF Mobile

In the current version of ADF Mobile the ADF DataControls ( URL and WS ) only supports SOAP and JSON-XML. But this does not mean we cannot use JSON. To handle JSON we can use the  RestServiceAdapter and JSONBeanSerializationHelper classes. The RestServiceAdapter will handle the Rest Service and JSONBeanSerializationHelper helps us converting JSON to Java.

I made a little ADF Mobile demo based on the Google Maps Geocoder and use this url to test it,+Mountain+View,+CA&sensor=true

with this as result

We start by creating an Url Connection with as value

Next is a new Class which can be used a managed bean or as a Java DataControl.

Here we do the following steps.

Create the RestServiceAdapter

RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();

Use our Url Connection

HTTP Get operartion

Append the url with our search parameters

Send and wait for the result.
response = restServiceAdapter.send("");

Next step is using the JSON deserialization, here we will use the JSONBeanSerializationHelper class.
ServiceResult responseObject = (ServiceResult)jsonHelper.fromJSON(ServiceResult.class, response); 

ServiceResult class will be used as output, too bad I can't use generics or annotations to control the JSON deserialization. So I will use JSONArray in case of 1 or more results.

import oracle.adfmf.json.JSONArray;
public class ServiceResult {
   private String status;
   private JSONArray results;

JSONBeanSerializationHelper will look for attributes called .type and if that contains a class name then it will use that class for deserialization but I can't change the Google Maps service.

So I made my own Helper class which converts all JSONArray or JSONObject to the right class and attributes.

geoResult = GeocoderHelper.transformObject(responseObject).getResults();

Here is my the helper class

Now we are ready to use it in a managed bean or generate an ADF DataControl on it.
with this as result.

You can find my demo code on Github

Here the pictures of the application in the IPad emulator.

Sunday, October 7, 2012

Build and Deploy OSB projects with Maven

2 years ago I already did the same with ANT and now I migrated these scripts to Maven. These Maven poms can still do the same like my ANT scripts.
  • Build and deploy an OSB OEPE workplace
  • Build one OSB project.
  • Export OSB projects from an OSB server and generate a customization plan.
Here you can find my code or the PS6 version
or with the new PS6 configjar tool which can create offline OSB exports without OEPE 

Also the readme contains some examples how to this from Java without the help of Maven or Ant.

I based my scripts on the following software and folders

My Environment Oracle OSB PS5 or with Maven 3.0.4

JVM                         = JDK 1.7_07 x64
Middleware home      = /opt/oracle/wls/wls11g
OSB & Oracle home = /opt/oracle/wls/wls11g/Oracle_OSB1
WebLogic home       = /opt/oracle/wls/wls11g/wlserver_10.3
Oepe home               = /opt/oracle/wls/wls11g/oepe11.1.1.8

My Maven settings.xml

run . to set all the Maven, Java variables.

To build a project or the whole OEPE workspace use this
mvn package

To deploy or export an existing OSB server use this target-env=dev so it uses the right Maven profile for the WebLogic Settings
mvn deploy -Dtarget-env=dev

Prepare a release
mvn release:prepare

Perform a release
mvn release:perform -Dtarget-env=dev

the pom.xml in the Maven_osb_ps5 folder build the whole source folder workspace, this generates a jar in the export folder with the same name as your pom definition.

the pom.xml in the Maven_osb_ps5/source/ReliableMessageWS and Maven_osb_ps5/source/XSDvalidation folder build only this project and generate a jar in the export folder with the same name as your pom definition.

the pom.xml in the Maven_osb_ps5/export folder export everything from the OSB server and puts the jar in the import folder.

Here is an example of a pom which build and deploys the whole OSB OEPE workspace.
This pom has the following plugins

  • exec-maven-plugin for building the OSB jar and deploy the jar to the OSB server, 
  • maven-assembly-plugin for adding the OSB jar as maven artifact 
  • maven-release-plugin for OSB releases. 

And here the assembly to add the generated OSB jar to Maven artifact