EJB design: Audit or History implementation in CMP
Is there any design pattern available to implement Audit or History functionality in CMP? For example, I have a customer table, If a customer updates his address, I want to store the old data in my audit tables. I don't want to couple the audit/history logic with my business logic, because I may want to turn it on or off at anytime.
- Posted by: Senthil Chinnaiyan
- Posted on: April 06 2004 16:10 EDT
- Audit or History implementation in CMP by Paul Strack on April 06 2004 19:59 EDT
- Audit or History implementation in CMP by Erik Sliman on April 07 2004 04:08 EDT
- Audit or History implementation in CMP by Jirawat Uttayaya on April 07 2004 21:28 EDT
I suggest you implement "logging" methods in the appropriate EJB lifecycle methods, such as ejbPostCreate() and ejbStore(). You can use a tool like Log4J to log changes whereever you need them (file, database, etc.). Log4J also allows you to configure what is and is not logged.
There are two parts to your question... time audit and user audit.
I have two layers for development: OSnetHelper, which does not involve any user security. Then there is JoshuaBranch AS (JB-AS), which provides security services, and is built on top of OSnetHelper.
OSnetHelper provides time stamping properties for CMP beans. You can have your CMP beans subclass a class in OSnetHelper that adds addTime and modTime properties. You'll still have to add them in your XML descriptors.
In your create methods, you simply call a method called onCreate() that sets the timestamps for new entries. For existing entries, I'm not sure of an easy way to integrate it without security, so I'll continue with the security additions.
There's no easy way to implement user auditing in CMP beans unless you somehow make your CMP beans "security aware". In other words, they have to know the current user's ID. I'm not sure it's worth the trouble, so for now I simply require the create and update business methods, which are security aware, to call the addBy(Long userId) and modBy(Long userId) methods.
In my case, I rely on timestamping in the database for the modTime() property. However, one could easily an extended modBy() method that called modBy() and modTime(). This, still, requires security integration to ultimately invoke modTime().
I'd like to open source OSnetHelper, but just don't have time right now. I can't even decide which open source license is right for it. Plus, since JB-AS depends on it, I'm concerned that publicly changing it could cripple compatibility with JB-AS, which is priority number one right now. Nevertheless, OSnetHelper.jar currently comes with JB-AS.
I hope this helps.
http://as.JoshuaBranch.com application security today
Actually, getting the userId in an EJB is pretty easy:
String userId = ejbContext.getCallerPrincipal().getName();
This assumes you are using J2EE security. If you have a custom security implementation, you may need to pass the userId around.
For time audit, you can use a database timestamp (if your audit trail goes in the database) or the System timestamp (if your audit trail goes in a log file). Log4J can automate this for you.
The cleanest way (my way?) to do it is to use Oracle triggers
or the equivalent for your DB.
Everytime someone does an Insert, Delete, or an Update
on a table, have a trigger write the change info into an audit