The world has moved to Java EE 7 (released June 2013) and it has been 5 years since Java EE 6 was launched (December 2009).
Oracle Identity Manager 11g R2 PS2
- Is certified/runs on Java EE 5
- Uses Spring for many of the features which come bundled within Java EE 5/6 and are well established ‘standards‘…. I wonder why?
So the question really is…….
Can standard Java EE functionality be better leveraged?
Tried to explore this, came up with a bunch of scenarios which have been explained with the help of examples
- Using Interceptors
All cross cutting concerns/repetitive functionality can be implemented using standard Java EE Interceptors (javax.interceptor.Interceptor) e.g. logging, auditing etc
Benefits
- Non duplication of code/functionality
- Cohesive class design
//Contains business logic for Auditing import javax.ejb.Stateless; @Stateless public class AuditBiz { //business logic for Audit operations public void performAudit(){ //perform audit } }
//This Interceptor can be applied generically to any method in an EJB import javax.inject.Inject; import javax.interceptor.Interceptor; import javax.interceptor.InvocationContext; @Interceptor public class AuditInterceptor { //Leverages an existing EJB and its business logic for performing audit related operations @Inject private AuditBiz auditOps; public void audit(InvocationContext context){ try{ auditOps.performAudit(); context.proceed(); }catch(Exception e){ } } }
Follow the post until the end for the EJB examples in order to see how the above Interceptor is actually utilized
- Leveraging CDI
The CDI framework can be interwoven within the implementation for communication between disparate parts of the application and for ‘light weight’ intra-application messaging system (using the javax.enterprise.event.Event and javax.enterprise.event.Observes annotation pattern along with appropriate javax.inject.Qualifier objects ). This will help in implementing loosely-coupled without overhead of listener registrations etc
Benefits
- Loosely coupled way of implementing observer-producer pattern – Observer is not aware of the Producer and vice-versa
- No overhead of explicitly ‘registering‘ the Observers to a specific consumer
//A class representing an event - such as user creation etc public class BusinessEvent { private String data; public String fetchData(){ return data; } }
import javax.enterprise.event.Event; import javax.inject.Inject; //Event producer class - responsible for intercepting the events and catapulting them for consumption public class BusinessEventProducer { @Inject Event<BusinessEvent>; eventSink; public void produceEvent(){ //a business event e.g. a user creation event BusinessEvent userCreationEvent = new BusinessEvent(); //notify the observers //Note: No explicit oberserver 'registration' required - power of Java EE and CDI ! eventSink.fire(userCreationEvent); } }
Where is the Event observer/consumer? Read on…
- RESTful interfaces – In Vogue !
The JAX-RS API can be leveraged to provide a RESTful interface for OIM. The only ‘standards‘ based gateway available for OIM is via SPML – but I have to say that its cumbersome to say the least and not feature rich.
A RESTful API is a must.
RESTFul API equivalents should be available for all major modules including
- User Management operations
- Password Management – this module was recently exposed via the SPML interface (from 11g R2 PS1).
- Reconciliation Operations – to collect data via other channels instead of querying the database. The OIM database really ought to be a ‘black box’ with well defined interfaces so that we as developers/integration specialists do not have to resort to writing lengthy database queries and Stored Procs
- Audit Operations – to collect real time audit statistics and much more … this was just the tip of iceberg……!
Benefits
Having a REST interface for OIM would open the flood gates for Mobile integration. This in turn will help expose specific features/functionality via Mobile Apps which in my opinion can turn out to be a huge business enabler.
Think RESTful, Think Mobile ! !
import javax.ejb.Stateless; //sample bean implementing User CRUD operations @Stateless public class UserManagementImpl { public void create(){ //business logic } public void lookup(){ //business logic } public void update(){ //business logic } public void delete(){ //business logic } }
import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; //RESTFul facade/gateway for exposing user management operations @Path("rest/oim/userOps") public class UserOpsRESTFacade { //leverage existing EJB containing business implementation for user operations @Inject private UserManagementImpl userOpsBizImpl; //expose functionality via simple methods/contracts //enable JSON and XML as data format @Path("create") @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public void createUser(){ userOpsBizImpl.create(); } @Path("update") @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public void updateUser(){ userOpsBizImpl.update(); } @Path("search") @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public void search(){ userOpsBizImpl.lookup(); } @Path("delete") @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public void deleteUser(){ userOpsBizImpl.delete(); } }
- Leverage EJB 3.1
The business layer is based on standard J2EE patterns like the Business Delegate/Service Locator. These are used to shield the EJB clients from being exposed to all the logic of performing JNDI lookup calls. There seems to be a proliferation of interfaces/classes – Business interface, Delegate interface, Extended interface, Remote interface, actual implementation. Can this be simplified?
//Local interface for use within internal clients within the container //e.g. UI interface public interface OIMBizLocal { public void localOp(); public void processEvent(BusinessEvent event); }
//Remote interface for ecternal clients public interface OIMBizRemote { public void remoteOp(); }
//Actual implementation of the interface import javax.ejb.Local; import javax.ejb.Remote; import javax.ejb.Stateless; import javax.enterprise.event.Observes; import javax.interceptor.Interceptors; @Stateless //specifying the Remote interface @Remote(OIMBizRemote.class) //specifying the Local interface @Local(OIMBizLocal.class) //Its leveraging the Audit interceptor to ensure that Auditing is seamlessly applicalble for all its methods @Interceptors(AuditInterceptor.class) public class OIMBizImpl implements OIMBizLocal, OIMBizRemote{ @Override public void remoteOp() { //business logic } @Override public void localOp() { //business logic } //the @Obeserver annotation is all you need to specify this method as a 'listener' for //BusinessEvent objects @Override public void processEvent(@Observes BusinessEvent event) { //leverage the event object to perform concrete actions String eventData = event.fetchData(); } }
While external clients have to use remote EJB interfaces, the container modules should strictly use Dependency Injection to reuse any of the business logic
import javax.inject.Inject; //Internal layer of the application public class InternalUIBean { //leveraging the already exising EJB via simple Dependency Injection @Inject private OIMBizLocal bizImpl; public void someUIOp(){ bizImpl.localOp(); } }
EJB 3.1 comes with concept of portable and standardized JNDI names based on combo of EAR, Module and EJB interface name. These can be used to perform JNDI lookups.
e.g. java:global/WebApp/StatefulCartBean!business.facade.StatefulCartRemote
All this was Java EE 5/6. I haven’t even started with Java EE 7 yet ! 😉
All those awesome APIs
- WebSockets
- JSON Processing
- Concurrency Utilities
- Batch Applications
- JAX-RS Client API !
- Simplified JMS API
Skipping the API usage examples for now. Leaving it to a Java EE 7 specific post…..
I can’t even imagine how these can be leveraged to dish out an amazing piece of software! That’s probably why I am just sitting and blogging about this .. ha ha! I guess we will have to wait until Weblogic gets certified on Java EE 7 (via 12.1.4) which again will probably be somewhere in Q4 of 2014 (please don’t quote me on this!). Having said that, the latest version (as of writing this post) 12.1.2 has packed quite a punch in terms of incorporating many Java EE 7 related specifications including support for
- WebSockets
- JAX-RS 2.0
- JSON bindings via Oracle TopLink and much more.
Cloud Support?
Java EE 6 in general was never actually ‘standardized’ or built for the cloud to begin with. Java EE 7 pretty much ‘missed the bus’ as far as Cloud related standardization is concerned, due to ongoing work on other ‘important’ specifications/APIs. Java EE 8 might be the one coming up with standard cloud related specifications. But we have to wait until year 2017-2018 (maybe?)
OIM on Weblogic 12c is something I am looking forward to as I feel that it is going to be the key to catapulting OIM to the Cloud.
Closing notes
It’s easy to sit and blog away about what should be done. I don’t want to take anything away from OIM as a product. It is pretty awesome. But, wouldn’t it just be better if pure Java EE was used? How easy would that make for it to be ‘certified‘ on more application servers, instead of just Oracle Weblogic 11g (10.3.6) and IBM Websphere (7.0) .
Java EE 6 certification for OIM would mean possibility of support for other application servers such as Red Hat’s JBoss EAP 6, Apache Geronimo 3.0 etc
More certified platforms == more opportunities !!!!
Time to sign off ! Until then… Happy Reading, Happy Coding, Happy Hacking 🙂