Generally in application when we add some data or
delete data from tables we will use persistence objects.

Once we fill the data in these objects then we will
store into database this is called Hibernate Persistence logic.

So in any record or data going to add in the
database it’s should use the POJO class and we can call these object as Model
Objects.

Model object is simple java class consist of setters
and getters methods so that we will use these object when want store data in database.
Each row in table will mapping to Model object instance before perform any
database action.

So simply we can say any action like add, delete, read
and update going to perform then it need
Model object instance and the model object should be modify or create.

If we able identify these actions and track then we
can hold the all the information with respect to each and every thing which is
going in the application.

Liferay have used great concept called Model Listeners
so that we can use these Listeners to identify the changes in the Model objects.

Liferay
Model Listeners:

Liferay Model listeners are event listeners which will
be invoked or called when the changes occurred in the model objects.

For each model object we have model listener so it
will listen the events or actions which is performed on model object. We can
create model listener for any model class in the liferay.

If we want create new listener for existed model
which are in portal level we will use the hook to do these job.We need to override
some portal properties thorogh the hook

The custom listener class should implement the ModelListener
interface and it has some abstract methods we need to implement those. These
methods will be called when the changes happened in the model object.

The
following are methods in ModelListener interface
and its methods

publicinterfaceModelListener<T>
{

publicvoid
onAfterAddAssociation(

Object classPK, String
associationClassName,

Object associationClassPK)

throws
ModelListenerException;

publicvoid onAfterCreate(T
model) throws ModelListenerException;

publicvoid onAfterRemove(T
model) throws ModelListenerException;

publicvoid
onAfterRemoveAssociation(

Object classPK, String
associationClassName,

Object
associationClassPK)

throws
ModelListenerException;

publicvoid onAfterUpdate(T
model) throws ModelListenerException;

publicvoid
onBeforeAddAssociation(

Object classPK, String
associationClassName,

Object
associationClassPK)

throws
ModelListenerException;

publicvoid onBeforeCreate(T
model) throws ModelListenerException;

publicvoid onBeforeRemove(T
model) throws ModelListenerException;

publicvoid
onBeforeRemoveAssociation(

Object classPK, String
associationClassName,

Object
associationClassPK)

throws
ModelListenerException;

publicvoid onBeforeUpdate(T
model) throws ModelListenerException;

}

The
concept is simple we will use respective model listeners and at the time of changes
made in model objects then respective listener methods will be called. We will
use some business logic in the Model Listener implementation methods to capture
the action and store in our tables according to convenient.

Audit
Message:

We will use some generic object to capture
respective model and its actions data so that it will be common for all the
models.

We will follow some message pattern so that all
models will capture such information place in Audit Message object.

The following is audit message class properties.

publicclassAuditMessage{

private JSONObject _additionalInfo;

private String _className;

private String _classPK;

private String _clientHost;

private String _clientIP;

privatelong_companyId = -1;

private String _eventType;

private String _message;

private String _serverName;

privateint_serverPort;

private String _sessionID;

private Date _timestamp;

privatelong_userId = -1;

private String _userName;

}

Message
Bus:

Message bus is one of the concepts in liferay so
that we can create some destinations and its respective listeners to send the information
and perform further actions through its respective listeners.

Whenever any event is generated we will post
information to configured destinations as soon as information posted in destination
respective liters will be listening and will perform further activities.

Model Listeners is different from Message Bus
Destination listeners both are not same.

Now
abstract the concept:

Model leisters are the responsible to identify the
changes in the model class.

As soon as changes listen by the model listeners and
each model listener have some methods bases on change type or event type inside
these methods based on model event type we will prepare generic Audit Message.

Once Audit Message is prepared we will post this
message in particular destination using Liferay Message Bus or we can say
routing message to respective destination.

As soon as Message posted in Destination respective event
listener will be invoked now we will capture the information from Audit Message
then we will save into our data base tables.

Finally model object events information is stored as
Audit Event table and the table consist of the columns same as the properties in
Audit Message.

So this concept we can apply for any model object so
that we can capture the information.

The above code when we add role then it will be
invoked and it will prepare Audit Message routing to respective destination.

As soon as it reach destination respective listener
will be invoked and the audit data will be stored in Audit Event table.

Note:

We have audit hook and audit portlet to complete
audit functionality in portal.

Audit
Hook:

Audit hook is responsible to create model listeners for
existed Model classes in portal and inside Model Listener we will create audit
message in post into destination or we can say route the message to particular destination.

Audit Portlet is responsible to show the audit
information to admin the control panel.

In the portlet we have one entity called in Audit
Event and it’s consisting of required columns to store audit information.

Audit portlet also consist of message bus
configuration in messaging-spring.xml and this file should be available in
portlet /WEB-INF/src/META-INF path.

And we need to specify the messaging-spring.xml file
information in service.properties and it’s should available in /WEB-INF/src

We have another spring configuration file called auit-spring.xml
file it consist of configuration related audit spring beans. This file should
be available in portlet /WEB-INF/src/META-INF
path. We need create and add configuration

We need to specify the auit-spring.xml file
information in service.properties and it’s should available in /WEB-INF/src

In the portlet we need to change the database column
types through portlet-model-hints.xml file.
This file should be available in portlet /WEB-INF/src/META-INF
path

Deployment
and Working

Step:
1

Before deploy these portlet we need to enable AuditFilter
and override portal properties through portal-ext.properties file and it
should be available in Liferay Home path.

#
Enable the audit filter

com.liferay.portal.servlet.filters.audit.AuditFilter=true

Step:
2

.lpg files and placed in
liferay deploy directory so that it will be deployed.

Step: 3

After successful deployments of both hook and
portlet then go to control panel in portal section you can see the audit
portlet.

Access
the portlet

Login as Admin in the liferay portal

Go to control panel

See the audit portlet in the users section

Access audit portlet then you can see all audit information
in grid.

You can also search the audit information based on different
search terms.

Click on any Audit event in data grid then you can
see full details of respective event.