mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
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:
@@ -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>
|
@@ -1,6 +1,8 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
|
||||||
<!-- Default Audit Configuration -->
|
<!--
|
||||||
|
An example of how user login details can be captured.
|
||||||
|
-->
|
||||||
|
|
||||||
<Audit
|
<Audit
|
||||||
xmlns="http://www.alfresco.org/repo/audit/model/3.2"
|
xmlns="http://www.alfresco.org/repo/audit/model/3.2"
|
||||||
@@ -10,27 +12,32 @@
|
|||||||
|
|
||||||
<DataExtractors>
|
<DataExtractors>
|
||||||
<DataExtractor name="simpleValue" registeredName="auditModel.extractor.simpleValue"/>
|
<DataExtractor name="simpleValue" registeredName="auditModel.extractor.simpleValue"/>
|
||||||
<DataExtractor name="nullValue" registeredName="auditModel.extractor.nullValue"/>
|
|
||||||
</DataExtractors>
|
</DataExtractors>
|
||||||
|
|
||||||
<DataGenerators>
|
<DataGenerators>
|
||||||
<DataGenerator name="personFullName" registeredName="auditModel.generator.personFullName"/>
|
<DataGenerator name="personFullName" registeredName="auditModel.generator.personFullName"/>
|
||||||
<DataGenerator name="authenticatedUser" registeredName="auditModel.generator.user"/>
|
|
||||||
</DataGenerators>
|
</DataGenerators>
|
||||||
|
|
||||||
<PathMappings>
|
<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>
|
</PathMappings>
|
||||||
|
|
||||||
<Application name="AlfrescoRepository" key="repository">
|
<Application name="AuditExampleLogin1" key="auditexamplelogin1">
|
||||||
<AuditPath key="login">
|
<AuditPath key="login">
|
||||||
<AuditPath key="no-error">
|
<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>
|
||||||
<AuditPath key="error">
|
<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>
|
||||||
</AuditPath>
|
</AuditPath>
|
||||||
</Application>
|
</Application>
|
||||||
|
|
||||||
|
<Application name="AuditExampleLogin2" key="auditexamplelogin2">
|
||||||
|
<AuditPath key="login">
|
||||||
|
<GenerateValue key="user" dataGenerator="personFullName"/>
|
||||||
|
</AuditPath>
|
||||||
|
</Application>
|
||||||
|
|
||||||
</Audit>
|
</Audit>
|
@@ -166,10 +166,10 @@
|
|||||||
<![CDATA[entry.audit_time < #auditToTime#]]>
|
<![CDATA[entry.audit_time < #auditToTime#]]>
|
||||||
</isNotNull>
|
</isNotNull>
|
||||||
<isNotNull prepend="and" property="searchKeyId">
|
<isNotNull prepend="and" property="searchKeyId">
|
||||||
sp_kpl.key_prop_id = #searchKeyId#
|
sp_pl.key_prop_id = #searchKeyId#
|
||||||
</isNotNull>
|
</isNotNull>
|
||||||
<isNotNull prepend="and" property="searchValueId">
|
<isNotNull prepend="and" property="searchValueId">
|
||||||
sp_mpl.value_prop_id = #searchValueId#
|
sp_pl.value_prop_id = #searchValueId#
|
||||||
</isNotNull>
|
</isNotNull>
|
||||||
</dynamic>
|
</dynamic>
|
||||||
</sql>
|
</sql>
|
||||||
@@ -208,12 +208,9 @@
|
|||||||
alf_audit_app app
|
alf_audit_app app
|
||||||
join alf_audit_entry entry on (entry.audit_app_id = app.id)
|
join alf_audit_entry entry on (entry.audit_app_id = app.id)
|
||||||
|
|
||||||
<isNotNull property="searchKeyId">
|
<isEqual property="keyOrValueSearch" compareValue="true">
|
||||||
join alf_prop_link sp_kpl on (sp_kpl.root_prop_id = entry.audit_values_id)
|
join alf_prop_link sp_pl on (sp_pl.root_prop_id = entry.audit_values_id)
|
||||||
</isNotNull>
|
</isEqual>
|
||||||
<isNotNull property="searchValueId">
|
|
||||||
join alf_prop_link sp_mpl on (sp_mpl.root_prop_id = entry.audit_values_id)
|
|
||||||
</isNotNull>
|
|
||||||
|
|
||||||
join alf_prop_link pl on (pl.root_prop_id = entry.audit_values_id)
|
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)
|
join alf_prop_value pv on (pl.value_prop_id = pv.id)
|
||||||
@@ -236,12 +233,9 @@
|
|||||||
alf_audit_app app
|
alf_audit_app app
|
||||||
join alf_audit_entry entry on (entry.audit_app_id = app.id)
|
join alf_audit_entry entry on (entry.audit_app_id = app.id)
|
||||||
|
|
||||||
<isNotNull property="searchKeyId">
|
<isEqual property="keyOrValueSearch" compareValue="true">
|
||||||
join alf_prop_link sp_kpl on (sp_kpl.root_prop_id = entry.audit_values_id)
|
join alf_prop_link sp_pl on (sp_pl.root_prop_id = entry.audit_values_id)
|
||||||
</isNotNull>
|
</isEqual>
|
||||||
<isNotNull property="searchValueId">
|
|
||||||
join alf_prop_link sp_mpl on (sp_mpl.root_prop_id = entry.audit_values_id)
|
|
||||||
</isNotNull>
|
|
||||||
|
|
||||||
<include refid="select_AuditEntriesWhereSnippet"/>
|
<include refid="select_AuditEntriesWhereSnippet"/>
|
||||||
<include refid="select_AuditEntriesOrderBySnippet"/>
|
<include refid="select_AuditEntriesOrderBySnippet"/>
|
||||||
|
@@ -281,7 +281,6 @@ db.pool.abandoned.log=false
|
|||||||
|
|
||||||
# Audit configuration
|
# Audit configuration
|
||||||
audit.enabled=false
|
audit.enabled=false
|
||||||
audit.repository.enabled=true
|
|
||||||
audit.cmischangelog.enabled=true
|
audit.cmischangelog.enabled=true
|
||||||
|
|
||||||
# System Configuration
|
# System Configuration
|
||||||
|
@@ -448,6 +448,11 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
ParameterCheck.mandatory("rootPath", rootPath);
|
ParameterCheck.mandatory("rootPath", rootPath);
|
||||||
AuditApplication.checkPathFormat(rootPath);
|
AuditApplication.checkPathFormat(rootPath);
|
||||||
|
|
||||||
|
if (values == null || values.isEmpty() || !areAuditValuesRequired())
|
||||||
|
{
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
// Log inbound values
|
// Log inbound values
|
||||||
if (loggerInbound.isDebugEnabled())
|
if (loggerInbound.isDebugEnabled())
|
||||||
{
|
{
|
||||||
@@ -464,11 +469,6 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
loggerInbound.debug(sb.toString());
|
loggerInbound.debug(sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values == null || values.isEmpty() || !areAuditValuesRequired())
|
|
||||||
{
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the key paths using the session root path
|
// Build the key paths using the session root path
|
||||||
Map<String, Serializable> pathedValues = new HashMap<String, Serializable>(values.size() * 2);
|
Map<String, Serializable> pathedValues = new HashMap<String, Serializable>(values.size() * 2);
|
||||||
for (Map.Entry<String, Serializable> entry : values.entrySet())
|
for (Map.Entry<String, Serializable> entry : values.entrySet())
|
||||||
@@ -642,18 +642,46 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
{
|
{
|
||||||
// Persist the values
|
// Persist the values
|
||||||
entryId = auditDAO.createAuditEntry(applicationId, time, username, auditData);
|
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;
|
return auditData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -720,10 +748,21 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
// Done
|
// Done
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug("Extracted audit data: \n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
" Application: " + application + "\n" +
|
sb.append(
|
||||||
" Raw values: " + values + "\n" +
|
"\nExtracted audit data: \n" +
|
||||||
" Extracted: " + newData);
|
"\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;
|
return newData;
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@ package org.alfresco.repo.audit;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import org.alfresco.service.cmr.audit.AuditQueryParameters;
|
import org.alfresco.service.cmr.audit.AuditQueryParameters;
|
||||||
import org.alfresco.service.cmr.audit.AuditService;
|
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, 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())
|
for (String app : apps.keySet())
|
||||||
{
|
{
|
||||||
String name = app;
|
String name = app;
|
||||||
|
@@ -27,6 +27,7 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import javax.xml.bind.JAXBContext;
|
import javax.xml.bind.JAXBContext;
|
||||||
import javax.xml.bind.JAXBElement;
|
import javax.xml.bind.JAXBElement;
|
||||||
@@ -355,8 +356,8 @@ public class AuditModelRegistryImpl extends AbstractPropertyBackedBean implement
|
|||||||
*/
|
*/
|
||||||
public void start()
|
public void start()
|
||||||
{
|
{
|
||||||
auditApplicationsByKey = new HashMap<String, AuditApplication>(7);
|
auditApplicationsByKey = new TreeMap<String, AuditApplication>();
|
||||||
auditApplicationsByName = new HashMap<String, AuditApplication>(7);
|
auditApplicationsByName = new TreeMap<String, AuditApplication>();
|
||||||
auditPathMapper = new PathMapper();
|
auditPathMapper = new PathMapper();
|
||||||
|
|
||||||
// If we are globally disabled, skip processing the models
|
// If we are globally disabled, skip processing the models
|
||||||
|
@@ -154,4 +154,12 @@ public class AuditQueryParameters
|
|||||||
{
|
{
|
||||||
this.searchValueId = searchValueId;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user