Merged BRANCHES/DEV/DEREK/V3.4_GENERAL to HEAD:

22630: ALF-4106 AuditService: Return applications in alphabetical order
   22631: ALF-4106 AuditService: 'Audit' family of web scripts
   22632: ALF-4106 AuditService: Samples for documentation
   22635: ALF-4106 AuditService: Sample fix
   22642: ALF-4106 AuditService: Neater debug logging
   22643: ALF-4106 AuditService: Another sample
   22644: Added .sample to file extensions to include in line ending checks
   22654: Removed unnecessary INFO logging
   22655: Fixed ALF-4872: AuditService: Unable to restrict results to a specific value path


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22789 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2010-09-30 15:14:27 +00:00
parent 0105f86127
commit 0fdf71553a
8 changed files with 136 additions and 44 deletions

View File

@@ -0,0 +1,43 @@
<?xml version='1.0' encoding='UTF-8'?>
<!--
An example of how user login details can be captured.
-->
<Audit
xmlns="http://www.alfresco.org/repo/audit/model/3.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.alfresco.org/repo/audit/model/3.2 alfresco-audit-3.2.xsd"
>
<DataExtractors>
<DataExtractor name="simpleValue" registeredName="auditModel.extractor.simpleValue"/>
<DataExtractor name="nullValue" registeredName="auditModel.extractor.nullValue"/>
<DataExtractor name="nodeNameValue" registeredName="auditModel.extractor.nodeName"/>
<DataExtractor name="nodeTypeValue" registeredName="auditModel.extractor.nodeType"/>
</DataExtractors>
<PathMappings>
<PathMap source="/alfresco-api/post/NodeService/createNode" target="/auditexampleextractors"/>
</PathMappings>
<Application name="AuditExampleExtractors" key="auditexampleextractors">
<AuditPath key="create">
<AuditPath key="in">
<RecordValue key="a" dataExtractor="simpleValue" dataSource="/auditexampleextractors/args/parentRef" dataTrigger="/auditexampleextractors/no-error"/>
<RecordValue key="b" dataExtractor="simpleValue" dataSource="/auditexampleextractors/args/nodeTypeQName" dataTrigger="/auditexampleextractors/no-error"/>
<RecordValue key="c" dataExtractor="simpleValue" dataSource="/auditexampleextractors/args/assocTypeQName" dataTrigger="/auditexampleextractors/no-error"/>
<RecordValue key="d" dataExtractor="simpleValue" dataSource="/auditexampleextractors/args/assocQName" dataTrigger="/auditexampleextractors/no-error"/>
</AuditPath>
<AuditPath key="out">
<RecordValue key="a" dataExtractor="simpleValue" dataSource="/auditexampleextractors/result" dataTrigger="/auditexampleextractors/no-error"/>
</AuditPath>
<AuditPath key="derived">
<RecordValue key="parent-node-null" dataExtractor="nullValue" dataSource="/auditexampleextractors/args/parentRef" dataTrigger="/auditexampleextractors/no-error"/>
<RecordValue key="parent-node-name" dataExtractor="nodeNameValue" dataSource="/auditexampleextractors/args/parentRef" dataTrigger="/auditexampleextractors/no-error"/>
<RecordValue key="parent-node-type" dataExtractor="nodeTypeValue" dataSource="/auditexampleextractors/args/parentRef" dataTrigger="/auditexampleextractors/no-error"/>
</AuditPath>
</AuditPath>
</Application>
</Audit>

View File

@@ -1,6 +1,8 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Default Audit Configuration -->
<!--
An example of how user login details can be captured.
-->
<Audit
xmlns="http://www.alfresco.org/repo/audit/model/3.2"
@@ -10,27 +12,32 @@
<DataExtractors>
<DataExtractor name="simpleValue" registeredName="auditModel.extractor.simpleValue"/>
<DataExtractor name="nullValue" registeredName="auditModel.extractor.nullValue"/>
</DataExtractors>
<DataGenerators>
<DataGenerator name="personFullName" registeredName="auditModel.generator.personFullName"/>
<DataGenerator name="authenticatedUser" registeredName="auditModel.generator.user"/>
</DataGenerators>
<PathMappings>
<PathMap source="/alfresco-api/post/AuthenticationService/authenticate" target="/repository/login"/>
<PathMap source="/alfresco-api/post/AuthenticationService/authenticate" target="/auditexamplelogin1/login"/>
<PathMap source="/alfresco-api/post/AuthenticationService/authenticate/no-error" target="/auditexamplelogin2/login"/>
</PathMappings>
<Application name="AlfrescoRepository" key="repository">
<Application name="AuditExampleLogin1" key="auditexamplelogin1">
<AuditPath key="login">
<AuditPath key="no-error">
<RecordValue key="user" dataExtractor="simpleValue" dataSource="/repository/login/args/userName"/>
<RecordValue key="user" dataExtractor="simpleValue" dataSource="/auditexamplelogin1/login/args/userName"/>
</AuditPath>
<AuditPath key="error">
<RecordValue key="user" dataExtractor="simpleValue" dataSource="/repository/login/args/userName"/>
<RecordValue key="user" dataExtractor="simpleValue" dataSource="/auditexamplelogin1/login/args/userName"/>
</AuditPath>
</AuditPath>
</Application>
<Application name="AuditExampleLogin2" key="auditexamplelogin2">
<AuditPath key="login">
<GenerateValue key="user" dataGenerator="personFullName"/>
</AuditPath>
</Application>
</Audit>

View File

@@ -166,10 +166,10 @@
<![CDATA[entry.audit_time < #auditToTime#]]>
</isNotNull>
<isNotNull prepend="and" property="searchKeyId">
sp_kpl.key_prop_id = #searchKeyId#
sp_pl.key_prop_id = #searchKeyId#
</isNotNull>
<isNotNull prepend="and" property="searchValueId">
sp_mpl.value_prop_id = #searchValueId#
sp_pl.value_prop_id = #searchValueId#
</isNotNull>
</dynamic>
</sql>
@@ -208,12 +208,9 @@
alf_audit_app app
join alf_audit_entry entry on (entry.audit_app_id = app.id)
<isNotNull property="searchKeyId">
join alf_prop_link sp_kpl on (sp_kpl.root_prop_id = entry.audit_values_id)
</isNotNull>
<isNotNull property="searchValueId">
join alf_prop_link sp_mpl on (sp_mpl.root_prop_id = entry.audit_values_id)
</isNotNull>
<isEqual property="keyOrValueSearch" compareValue="true">
join alf_prop_link sp_pl on (sp_pl.root_prop_id = entry.audit_values_id)
</isEqual>
join alf_prop_link pl on (pl.root_prop_id = entry.audit_values_id)
join alf_prop_value pv on (pl.value_prop_id = pv.id)
@@ -236,12 +233,9 @@
alf_audit_app app
join alf_audit_entry entry on (entry.audit_app_id = app.id)
<isNotNull property="searchKeyId">
join alf_prop_link sp_kpl on (sp_kpl.root_prop_id = entry.audit_values_id)
</isNotNull>
<isNotNull property="searchValueId">
join alf_prop_link sp_mpl on (sp_mpl.root_prop_id = entry.audit_values_id)
</isNotNull>
<isEqual property="keyOrValueSearch" compareValue="true">
join alf_prop_link sp_pl on (sp_pl.root_prop_id = entry.audit_values_id)
</isEqual>
<include refid="select_AuditEntriesWhereSnippet"/>
<include refid="select_AuditEntriesOrderBySnippet"/>

View File

@@ -281,7 +281,6 @@ db.pool.abandoned.log=false
# Audit configuration
audit.enabled=false
audit.repository.enabled=true
audit.cmischangelog.enabled=true
# System Configuration

View File

@@ -448,6 +448,11 @@ public class AuditComponentImpl implements AuditComponent
ParameterCheck.mandatory("rootPath", rootPath);
AuditApplication.checkPathFormat(rootPath);
if (values == null || values.isEmpty() || !areAuditValuesRequired())
{
return Collections.emptyMap();
}
// Log inbound values
if (loggerInbound.isDebugEnabled())
{
@@ -464,11 +469,6 @@ public class AuditComponentImpl implements AuditComponent
loggerInbound.debug(sb.toString());
}
if (values == null || values.isEmpty() || !areAuditValuesRequired())
{
return Collections.emptyMap();
}
// Build the key paths using the session root path
Map<String, Serializable> pathedValues = new HashMap<String, Serializable>(values.size() * 2);
for (Map.Entry<String, Serializable> entry : values.entrySet())
@@ -642,18 +642,46 @@ public class AuditComponentImpl implements AuditComponent
{
// Persist the values
entryId = auditDAO.createAuditEntry(applicationId, time, username, auditData);
// Done
if (logger.isDebugEnabled())
{
StringBuilder sb = new StringBuilder();
sb.append(
"\nNew audit entry: \n" +
"\tApplication ID: " + applicationId + "\n" +
"\tEntry ID: " + entryId + "\n" +
"\tValues: " + "\n");
for (Map.Entry<String, Serializable> entry : values.entrySet())
{
sb.append("\t\t").append(entry).append("\n");
}
sb.append("\n\tAudit Data: \n");
for (Map.Entry<String, Serializable> entry : auditData.entrySet())
{
sb.append("\t\t").append(entry).append("\n");
}
logger.debug(sb.toString());
}
}
else
{
// Done ... nothing
if (logger.isDebugEnabled())
{
StringBuilder sb = new StringBuilder();
sb.append(
"\nNothing audited: \n" +
"\tApplication ID: " + applicationId + "\n" +
"\tEntry ID: " + entryId + "\n" +
"\tValues: " + "\n");
for (Map.Entry<String, Serializable> entry : values.entrySet())
{
sb.append("\t\t").append(entry).append("\n");
}
logger.debug(sb.toString());
}
}
// Done
if (logger.isDebugEnabled())
{
logger.debug(
"New audit entry: \n" +
" Application ID: " + applicationId + "\n" +
" Entry ID: " + entryId + "\n" +
" Values: " + values + "\n" +
" Audit Data: " + auditData);
}
return auditData;
}
@@ -720,10 +748,21 @@ public class AuditComponentImpl implements AuditComponent
// Done
if (logger.isDebugEnabled())
{
logger.debug("Extracted audit data: \n" +
" Application: " + application + "\n" +
" Raw values: " + values + "\n" +
" Extracted: " + newData);
StringBuilder sb = new StringBuilder();
sb.append(
"\nExtracted audit data: \n" +
"\tApplication: " + application + "\n" +
"\tValues: " + "\n");
for (Map.Entry<String, Serializable> entry : values.entrySet())
{
sb.append("\t\t").append(entry).append("\n");
}
sb.append("\n\tNew Data: \n");
for (Map.Entry<String, Serializable> entry : newData.entrySet())
{
sb.append("\t\t").append(entry).append("\n");
}
logger.debug(sb.toString());
}
return newData;
}

View File

@@ -20,6 +20,7 @@ package org.alfresco.repo.audit;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import org.alfresco.service.cmr.audit.AuditQueryParameters;
import org.alfresco.service.cmr.audit.AuditService;
@@ -72,7 +73,7 @@ public class AuditServiceImpl implements AuditService
{
Map<String, org.alfresco.repo.audit.model.AuditApplication> apps = auditComponent.getAuditApplications();
Map<String, AuditApplication> ret = new HashMap<String, AuditApplication>(apps.size() * 2);
Map<String, AuditApplication> ret = new TreeMap<String, AuditApplication>();
for (String app : apps.keySet())
{
String name = app;

View File

@@ -27,6 +27,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
@@ -355,8 +356,8 @@ public class AuditModelRegistryImpl extends AbstractPropertyBackedBean implement
*/
public void start()
{
auditApplicationsByKey = new HashMap<String, AuditApplication>(7);
auditApplicationsByName = new HashMap<String, AuditApplication>(7);
auditApplicationsByKey = new TreeMap<String, AuditApplication>();
auditApplicationsByName = new TreeMap<String, AuditApplication>();
auditPathMapper = new PathMapper();
// If we are globally disabled, skip processing the models

View File

@@ -154,4 +154,12 @@ public class AuditQueryParameters
{
this.searchValueId = searchValueId;
}
/**
* @return Returns <tt>true</tt> if this object includes a key- or value-based search
*/
public boolean isKeyOrValueSearch()
{
return searchKeyId != null || searchValueId != null;
}
}