Auditing actions in the Correspondence Management solution

The Correspondence Management solution allows a number of actions, such as Create, Edit/Update, Revert, etc., over assets within the solution. Here is an approach to maintain an audit trail for each such action performed on an asset.

Before you go ahead with this approach, ensure that you have your development environment setup for the solution.

Overview

The overall approach used here is to register an AuditHandler that is registered against each action, such that it is invoked (from within the infrastructure) when the corresponding actions are performed over an asset. The handler can then have any custom implementation for managing the audit log, varying from as simple as a message in a log file to more complex management such as a database tuple.

Implementation

Here are the specific steps you need to take to enable the above.

  1. Create an AuditHandler class, that implements the com.adobe.livecycle.content.repository.action.ActionHandler interface, in the CorrespondenceManagementSolutionTemplate/Services project. You are then required to implement the preProcess() and postProcess() methods which are called before and after an action in performed respectively. One may choose to perform the audit logging in any one (or maybe both) of these methods. Here’s how your AuditHandler skeleton would look like:

    package com.adobe.icc; 
    
    import java.util.Map;
    import com.adobe.icc.dbforms.obj.Asset;
    import com.adobe.livecycle.content.repository.action.ActionHandler;
    import com.adobe.livecycle.content.repository.action.ActionType; 
    
    /**
     * Custom audit handler that audits actions in the CM solution.
     */
    public class AuditHandler implements ActionHandler { 
    
        private static final String PREFIX = "PREFIX";
        /**
         * This method is invoked just prior to the action being performed.
         */
        public void preProcess(String nodeType, ActionType actionType, Object obj, Map<String, Object> arg1)
        {
            Asset asset = (Asset) obj; // obj is the Asset object, and can hence be cast.
            // perform your audit logging here - for e.g., a log statement - logger.info("Asset being created [" + asset.getName() + "] by user : " + SecurityContextHolder.getContext().getAuthentication().getName());
        } 
    
        /**
         * This method is invoked just after the action has been performed.
         */
        public void postProcess(String nodeType, ActionType actionType, Object obj, Map<String, Object> arg1) {
            // perform your audit logging here -  - for e.g., a log statement - logger.info("Asset created [" + asset.getName() + "] by user : " + SecurityContextHolder.getContext().getAuthentication().getName());
        }
    }
  2. Add the following entry to the <bp:blueprint> section of CorrespondenceManagementSolutionTemplate\Services\resources\META-INF\spring\osgi-context.xmlfile:
    
    <bp:reference interface="com.adobe.livecycle.content.repository.RepositoryService" />
    
    
  3. Update the com.adobe.icc.bootstrap.AssetDefinitionDeployer class, under CorrespondenceManagementSolutionTemplate\Services\src\com\adobe\icc\bootstrap, to add a private member variable repositoryService of type com.adobe.livecycle.content.repository.RepositoryService:
    
    @Autowired
    private RepositoryService repositoryService;
    
    
  4. Register your handler for the necessary actions. To do so, add the following code to the afterPropertiesSet()method:
    
    List<ActionHandler> handlers = new ArrayList<ActionHandler>();
    handlers = new ArrayList<ActionHandler>();
    handlers.add(new AuditHandler()); 
    
    // registering the handler against the CREATE action of a Text asset.
    repositoryService.addActionHandlers(ActionHandlerService.APP_ROOT_GLOBAL, TextModule.class.getName(), ActionType.CREATE, handlers);
    
    // registering the handler against the EDIT/UPDATE action of a Text asset.
    repositoryService.addActionHandlers(ActionHandlerService.APP_ROOT_GLOBAL, TextModule.class.getName(), ActionType.UPDATE, handlers); 
    
    // register for other actions, as applicable
  5. Rebuild and redeploy the Solution template to get your changes in affect. For information on rebuilding and redeploying, see Building and deploying the CM Solution Template