Adding Audit Data


It's often not enough to simply store data in a relational database. Many applications need to keep information about who created each row, and when. Often, it is also necessary to know who last edited the data, and when. This type of data is referred to as audit data.

Audit data is a common requirement for enterprise applications. While it is possible to build audit data into your application, it is easier to let JBoss manage the audit data for you. JBoss can track the creation and modification of entity beans as additional persistent data. This data can exist only in the database to be used for administrative purposes, or you can map it onto persistent fields in your entity beans to be used by the application.

How do I do that?

Since all access to the entity beans is managed by the application server, JBoss should be able to easily track who is editing the bean data and when they are doing it. We say should because, as the application stands now, JBoss isn't enforcing any security on the EJB tier.


Note: Fortunately, JBoss isn't limited to J2EE security. JBoss allows you to replace the simple method permission checks with much more interesting policies.

When you configured the security policy in Chapter 5, you were only concerned about security into the web application. The beans are local EJBs with no remote view, so there is no need to worry about protecting them from access. J2EE role-based security is too primitive to do anything interesting at the EJB tier anyway, so we ignored the fact that we didn't have any security configuration on the EJB tier.

When you enable audit information, user information has to come into the EJB tier from the web tier to provide the user portion of the audit information. For that, you need a proper security domain linked to the application.

On the web tier, you linked to a security domain by adding a security-domain element to jboss-web.xml. On the EJB side, you need to add the same security-domain element to your jboss.xml file:

     <!DOCTYPE jboss PUBLIC               "-//JBoss//DTD JBOSS 4.0//EN"               "http://www.jboss.org/j2ee/dtd/jboss_4_0.dtd">     <jboss>         <security-domain>java:/jaas/todo</security-domain>     </jboss> 

Since the security domain is the same, java:/jaas/todo, JBoss will pass user information seamlessly from the web tier into the EJB tier. We've already declared all the bean methods as unchecked, so JBoss won't restrict access to the beans in any way. However, information about the current authenticated user is now available to the audit fields.

Four audit fields are available: created-by, created-time, updated-by, and updated-time. These correspond to the user and time information related to when the bean was created and the last time it was updated. You can enable each audit field by providing the corresponding element inside the audit element for an entity in jbosscmp-jdbc.xml.

JBoss configuration files should make enough sense by now that we can just jump to a complete example. For each audit field, you need to add a column-name element that supplies the column name in which JBoss should write the audit data. The following configuration adds all four audit fields to the task bean:

     <entity>         <ejb-name>Task</ejb-name>         <table-name>TODO_TASK</table-name>         <!-- cmp-field -->         <audit>             <created-by>                 <column-name>AUDIT_CREATED_BY</column-name>             </created-by>             <created-time>                 <column-name>AUDIT_CREATED_TIME</column-name>             </created-time>             <updated-by>                 <column-name>AUDIT_UPDATED_BY</column-name>             </updated-by>             <updated-time>                 <column-name>AUDIT_UPDATED_TIME</column-name>             </updated-time>         </audit>     </entity> 

The complete file is available in etc/audit/jbosscmp-jdbc.xml. You can add this file to the application by setting optional.dd to audit when building:

     [todo]$ ant -Doptional.dd=audit main deploy 

When you do this, JBoss will create the following table:

     CREATE TABLE TODO_TASK      (         TASK_ID VARCHAR(32) NOT NULL,          TASK_NAME VARCHAR(256),          TASK_USER VARCHAR(256),          TASK_START TIMESTAMP,          TASK_END TIMESTAMP,          AUDIT_CREATED_BY VARCHAR(256) NOT NULL,          AUDIT_CREATED_TIME TIMESTAMP NOT NULL,         AUDIT_UPDATED_BY VARCHAR(256) NOT NULL,          AUDIT_UPDATED_TIME TIMESTAMP NOT NULL,          CONSTRAINT PK_TODO_TASK PRIMARY KEY (TASK_ID)     ) 

If the type isn't to your liking, you can override type information for an audit field by specifying JDBC and SQL types, just as you can for CMP fields:

     <created-by>         <column-name>AUDIT_CREATED_BY</column-name>         <jdbc-type>VARCHAR</jdbc-type>         <sql-type>VARCHAR(40)</sql-type>     </created-by> 

These audit fields are stored in the database. You can use them in administrative tools, but the data isn't available to the application. That's a shame in terms of the ToDo application because the AUDIT_CREATED_BY and AUDIT_CREATED_TIME fields are, for all practical purposes, copies of the TASK_USER and TASK_STARTED fields. It would simplify the application a bit if we could merge the redundant columns and let JBoss populate the fields on object creation.


Note: It is more likely that you would simply add new CMP fields and map the audit data to them.

To do that, you need to replace the column-name element in the audit fields with a field-name element that links the audit field with an existing CMP field in the application:

     <audit>         <created-by>             <field-name>user</field-name>         </created-by>         <created-time>             <field-name>startedDate</field-name>         </created-time>     </audit> 

With this configuration, the schema reverts to its previous form without the separate audit fields:

     CREATE TABLE TODO_TASK      (         TASK_ID VARCHAR(32) NOT NULL,          TASK_NAME VARCHAR(256),          TASK_USER VARCHAR(256),          TASK_START TIMESTAMP,          TASK_END TIMESTAMP,          CONSTRAINT PK_TODO_TASK PRIMARY KEY (TASK_ID)     ) 

Here's how this works: if the application doesn't specify user or startedDate values when a bean instance is created, JBoss will populate the field with the appropriate audit information. The application obviously is doing this in the ejbCreate method of TaskBean, but it's easy enough to take that code out. The lines to remove are shown commented out in the following code:

     /** @ejb.create-method */     public String ejbCreate(String user, String name)         throws CreateException     {         setId(TaskUtil.generateGUID(this));         setName(name);         // setUser(user);          // setStartedDate(new Date(  ));         logger.debug("creating task " + getId(  ) + " for user " + user);         return null;     } 

If you make these changes and redeploy the application, you will find that JBoss will populate values exactly as expected.

What just happened?

You saw how to add audit information for any CMP entity bean. Audit fields work exactly like regular CMP fields, and you have control over both the name and the type of field. If you prefer to integrate the audit information into the bean itself, you can map the audit information onto any CMP field on the bean.



JBoss. A Developer's Notebook
JBoss: A Developers Notebook
ISBN: 0596100078
EAN: 2147483647
Year: 2003
Pages: 106

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net