mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Added 'enableAuditPath' and 'disableAuditPath'
- Various tests to see that the recorded data is changed - disabledPaths rely entirely on the property caching for fast retrieval git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@16271 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -38,6 +38,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<!-- V3.2 specific -->
|
<!-- V3.2 specific -->
|
||||||
<property name="auditModelRegistry" ref="auditModel.modelRegistry"/>
|
<property name="auditModelRegistry" ref="auditModel.modelRegistry"/>
|
||||||
|
<property name="propertyValueDAO" ref="propertyValueDAO"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- Public service idntifier -->
|
<!-- Public service idntifier -->
|
||||||
|
@@ -121,7 +121,9 @@ public class AuditBootstrapTest extends TestCase
|
|||||||
|
|
||||||
public void testGetApplicationId()
|
public void testGetApplicationId()
|
||||||
{
|
{
|
||||||
Long appId = auditModelRegistry.getAuditApplicationId(APPLICATION_TEST);
|
AuditApplication app = auditModelRegistry.getAuditApplication(APPLICATION_TEST);
|
||||||
|
assertNotNull(app);
|
||||||
|
Long appId = app.getApplicationId();
|
||||||
assertNotNull("No audit application ID for " + APPLICATION_TEST, appId);
|
assertNotNull("No audit application ID for " + APPLICATION_TEST, appId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -83,6 +83,50 @@ public interface AuditComponent
|
|||||||
/*
|
/*
|
||||||
* V3.2 from here on. Put all fixes to the older audit code before this point, please.
|
* V3.2 from here on. Put all fixes to the older audit code before this point, please.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable auditing (if it is not already enabled) for all paths that contain the given path.
|
||||||
|
* The path is the path as originally logged (see {@link #audit(String, String, Map)}) and
|
||||||
|
* not the path that the generated data may contain - although this would be similarly
|
||||||
|
* enabled.
|
||||||
|
* <p>
|
||||||
|
* If the enabled
|
||||||
|
*
|
||||||
|
* @param applicationName the name of the application being logged to
|
||||||
|
* @param path the audit path to enable auditing on
|
||||||
|
*
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
void enableAudit(String applicationName, String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable auditing (if it is not already disabled) for all paths that contain the given path.
|
||||||
|
* The path is the path as originally logged (see {@link #audit(String, String, Map)}) and
|
||||||
|
* not the path that the generated data may contain - although this would be similarly
|
||||||
|
* disabled.
|
||||||
|
* <p>
|
||||||
|
* If the path is <b>/x/y</b> then any data paths that start with <b>/x/y</b> will be stripped
|
||||||
|
* out <u>before</u> data generators and data recorders are applied. If the path represents
|
||||||
|
* the root path of the application, then auditing for that application is effectively disabled.
|
||||||
|
*
|
||||||
|
* @param applicationName the name of the application being logged to
|
||||||
|
* @param path the audit path to enable auditing on
|
||||||
|
*
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
void disableAudit(String applicationName, String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all disabled paths i.e. enable all per-path based auditing. Auditing may still be
|
||||||
|
* disabled globally. This is primarily for test purposes; applications should know which
|
||||||
|
* paths need {@link #enableAudit(String, String) enabling} or
|
||||||
|
* {@link #disableAudit(String, String) disabling}.
|
||||||
|
*
|
||||||
|
* @param applicationName the name of the application
|
||||||
|
*
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
void resetDisabledPaths(String applicationName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record a set of values against the given session. The map is a path - starting with '/'
|
* Record a set of values against the given session. The map is a path - starting with '/'
|
||||||
@@ -118,6 +162,8 @@ public interface AuditComponent
|
|||||||
* @param from the start search time (<tt>null</tt> to start at the beginning)
|
* @param from the start search time (<tt>null</tt> to start at the beginning)
|
||||||
* @param to the end search time (<tt>null</tt> for no limit)
|
* @param to the end search time (<tt>null</tt> for no limit)
|
||||||
* @param maxResults the maximum number of results to retrieve (zero or negative to ignore)
|
* @param maxResults the maximum number of results to retrieve (zero or negative to ignore)
|
||||||
|
*
|
||||||
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
void auditQuery(
|
void auditQuery(
|
||||||
AuditQueryCallback callback,
|
AuditQueryCallback callback,
|
||||||
@@ -135,6 +181,8 @@ public interface AuditComponent
|
|||||||
* @param searchKey the audit key path that must exist (<tt>null</tt> to ignore)
|
* @param searchKey the audit key path that must exist (<tt>null</tt> to ignore)
|
||||||
* @param searchString an audit value string that must exist (<tt>null</tt> to ignore)
|
* @param searchString an audit value string that must exist (<tt>null</tt> to ignore)
|
||||||
* @param maxResults the maximum number of results to retrieve (zero or negative to ignore)
|
* @param maxResults the maximum number of results to retrieve (zero or negative to ignore)
|
||||||
|
*
|
||||||
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
void auditQuery(
|
void auditQuery(
|
||||||
AuditQueryCallback callback,
|
AuditQueryCallback callback,
|
||||||
|
@@ -31,8 +31,11 @@ import java.net.UnknownHostException;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.repo.audit.extractor.DataExtractor;
|
import org.alfresco.repo.audit.extractor.DataExtractor;
|
||||||
@@ -42,6 +45,7 @@ import org.alfresco.repo.audit.model.AuditEntry;
|
|||||||
import org.alfresco.repo.audit.model.AuditModelRegistry;
|
import org.alfresco.repo.audit.model.AuditModelRegistry;
|
||||||
import org.alfresco.repo.audit.model.TrueFalseUnset;
|
import org.alfresco.repo.audit.model.TrueFalseUnset;
|
||||||
import org.alfresco.repo.domain.audit.AuditDAO;
|
import org.alfresco.repo.domain.audit.AuditDAO;
|
||||||
|
import org.alfresco.repo.domain.propval.PropertyValueDAO;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
|
||||||
@@ -759,6 +763,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private AuditModelRegistry auditModelRegistry;
|
private AuditModelRegistry auditModelRegistry;
|
||||||
|
private PropertyValueDAO propertyValueDAO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the registry holding the audit models
|
* Set the registry holding the audit models
|
||||||
@@ -769,6 +774,200 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
this.auditModelRegistry = auditModelRegistry;
|
this.auditModelRegistry = auditModelRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the DAO for manipulating property values
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
public void setPropertyValueDAO(PropertyValueDAO propertyValueDAO)
|
||||||
|
{
|
||||||
|
this.propertyValueDAO = propertyValueDAO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param application the audit application object
|
||||||
|
* @return Returns a copy of the set of disabled paths associated with the application
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Set<String> getDisabledPaths(AuditApplication application)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Long disabledPathsId = application.getDisabledPathsId();
|
||||||
|
Set<String> disabledPaths = (Set<String>) propertyValueDAO.getPropertyById(disabledPathsId);
|
||||||
|
return new HashSet<String>(disabledPaths);
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
// Might be an invalid ID, somehow
|
||||||
|
auditModelRegistry.loadAuditModels();
|
||||||
|
throw new AlfrescoRuntimeException("Unabled to get AuditApplication disabled paths: " + application, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
public void enableAudit(String applicationName, String path)
|
||||||
|
{
|
||||||
|
ParameterCheck.mandatory("applicationName", applicationName);
|
||||||
|
ParameterCheck.mandatory("path", path);
|
||||||
|
|
||||||
|
if (AlfrescoTransactionSupport.getTransactionReadState() != TxnReadState.TXN_READ_WRITE)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Auditing requires a read-write transaction.");
|
||||||
|
}
|
||||||
|
|
||||||
|
AuditApplication application = auditModelRegistry.getAuditApplication(applicationName);
|
||||||
|
if (application == null)
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("No audit application named '" + applicationName + "' has been registered.");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Check the path against the application
|
||||||
|
application.checkPath(path);
|
||||||
|
|
||||||
|
Long disabledPathsId = application.getDisabledPathsId();
|
||||||
|
Set<String> disabledPaths = getDisabledPaths(application);
|
||||||
|
|
||||||
|
// Remove any paths that start with the given path
|
||||||
|
boolean changed = false;
|
||||||
|
Iterator<String> iterateDisabledPaths = disabledPaths.iterator();
|
||||||
|
while (iterateDisabledPaths.hasNext())
|
||||||
|
{
|
||||||
|
String disabledPath = iterateDisabledPaths.next();
|
||||||
|
if (disabledPath.startsWith(path))
|
||||||
|
{
|
||||||
|
iterateDisabledPaths.remove();
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Persist, if necessary
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
propertyValueDAO.updateProperty(disabledPathsId, (Serializable) disabledPaths);
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug(
|
||||||
|
"Audit disabled paths updated: \n" +
|
||||||
|
" Application: " + applicationName + "\n" +
|
||||||
|
" Disabled: " + disabledPaths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Done
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
public void disableAudit(String applicationName, String path)
|
||||||
|
{
|
||||||
|
ParameterCheck.mandatory("applicationName", applicationName);
|
||||||
|
ParameterCheck.mandatory("path", path);
|
||||||
|
|
||||||
|
if (AlfrescoTransactionSupport.getTransactionReadState() != TxnReadState.TXN_READ_WRITE)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Auditing requires a read-write transaction.");
|
||||||
|
}
|
||||||
|
|
||||||
|
AuditApplication application = auditModelRegistry.getAuditApplication(applicationName);
|
||||||
|
if (application == null)
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("No audit application named '" + applicationName + "' has been registered.");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Check the path against the application
|
||||||
|
application.checkPath(path);
|
||||||
|
|
||||||
|
Long disabledPathsId = application.getDisabledPathsId();
|
||||||
|
Set<String> disabledPaths = getDisabledPaths(application);
|
||||||
|
|
||||||
|
// Shortcut if the disabled paths contain the exact path
|
||||||
|
if (disabledPaths.contains(path))
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug(
|
||||||
|
"Audit disable path already present: \n" +
|
||||||
|
" Path: " + path);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bring the set up to date by stripping out unwanted paths
|
||||||
|
Iterator<String> iterateDisabledPaths = disabledPaths.iterator();
|
||||||
|
while (iterateDisabledPaths.hasNext())
|
||||||
|
{
|
||||||
|
String disabledPath = iterateDisabledPaths.next();
|
||||||
|
if (disabledPath.startsWith(path))
|
||||||
|
{
|
||||||
|
// We will be superceding this
|
||||||
|
iterateDisabledPaths.remove();
|
||||||
|
}
|
||||||
|
else if (path.startsWith(disabledPath))
|
||||||
|
{
|
||||||
|
// There is already a superceding path
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug(
|
||||||
|
"Audit disable path superceded: \n" +
|
||||||
|
" Path: " + path + "\n" +
|
||||||
|
" Superceded by: " + disabledPath);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add our path in
|
||||||
|
disabledPaths.add(path);
|
||||||
|
// Upload the new set
|
||||||
|
propertyValueDAO.updateProperty(disabledPathsId, (Serializable) disabledPaths);
|
||||||
|
// Done
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug(
|
||||||
|
"Audit disabled paths updated: \n" +
|
||||||
|
" Application: " + applicationName + "\n" +
|
||||||
|
" Disabled: " + disabledPaths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
public void resetDisabledPaths(String applicationName)
|
||||||
|
{
|
||||||
|
ParameterCheck.mandatory("applicationName", applicationName);
|
||||||
|
|
||||||
|
if (AlfrescoTransactionSupport.getTransactionReadState() != TxnReadState.TXN_READ_WRITE)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Auditing requires a read-write transaction.");
|
||||||
|
}
|
||||||
|
AuditApplication application = auditModelRegistry.getAuditApplication(applicationName);
|
||||||
|
if (application == null)
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("No audit application named '" + applicationName + "' has been registered.");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Long disabledPathsId = application.getDisabledPathsId();
|
||||||
|
propertyValueDAO.updateProperty(disabledPathsId, (Serializable) Collections.emptySet());
|
||||||
|
// Done
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Removed all disabled paths for application " + applicationName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
@@ -801,13 +1000,27 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
// Check the path against the application
|
// Check the path against the application
|
||||||
application.checkPath(rootPath);
|
application.checkPath(rootPath);
|
||||||
// Get the model ID for the application
|
// Get the model ID for the application
|
||||||
Long applicationId = auditModelRegistry.getAuditApplicationId(applicationName);
|
Long applicationId = application.getApplicationId();
|
||||||
if (applicationId == null)
|
if (applicationId == null)
|
||||||
{
|
{
|
||||||
throw new AuditException("No persisted instance exists for audit application: " + applicationName);
|
throw new AuditException("No persisted instance exists for audit application: " + applicationName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Check if the root path is enabled or not
|
// Get all disabled paths
|
||||||
|
Set<String> disabledPaths = getDisabledPaths(application);
|
||||||
|
// Check if the root path has been disabled
|
||||||
|
// This is a fast check and will usually be activated if there are any exclusions
|
||||||
|
for (String disabledPath : disabledPaths)
|
||||||
|
{
|
||||||
|
if (rootPath.startsWith(disabledPath))
|
||||||
|
{
|
||||||
|
logger.debug(
|
||||||
|
"Audit values root path has been excluded by disabled paths: \n" +
|
||||||
|
" Application: " + application + "\n" +
|
||||||
|
" Root Path: " + rootPath);
|
||||||
|
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);
|
||||||
@@ -818,6 +1031,34 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
pathedValues.put(path, entry.getValue());
|
pathedValues.put(path, entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Eliminate any paths that have been disabled
|
||||||
|
Iterator<String> pathedValuesKeyIterator = pathedValues.keySet().iterator();
|
||||||
|
while(pathedValuesKeyIterator.hasNext())
|
||||||
|
{
|
||||||
|
String pathedValueKey = pathedValuesKeyIterator.next();
|
||||||
|
for (String disabledPath : disabledPaths)
|
||||||
|
{
|
||||||
|
if (pathedValueKey.startsWith(disabledPath))
|
||||||
|
{
|
||||||
|
// The pathed value is excluded
|
||||||
|
pathedValuesKeyIterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check if there is anything left
|
||||||
|
if (pathedValues.size() == 0)
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug(
|
||||||
|
"Audit values have all been excluded by disabled paths: \n" +
|
||||||
|
" Application: " + application + "\n" +
|
||||||
|
" Root Path: " + rootPath + "\n" +
|
||||||
|
" Values: " + values);
|
||||||
|
}
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
// Generate data
|
// Generate data
|
||||||
Map<String, DataGenerator> generators = application.getDataGenerators(pathedValues.keySet());
|
Map<String, DataGenerator> generators = application.getDataGenerators(pathedValues.keySet());
|
||||||
Map<String, Serializable> auditData = generateData(generators);
|
Map<String, Serializable> auditData = generateData(generators);
|
||||||
|
@@ -105,6 +105,17 @@ public class AuditComponentTest extends TestCase
|
|||||||
// Authenticate
|
// Authenticate
|
||||||
user = "User-" + getName();
|
user = "User-" + getName();
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(user);
|
AuthenticationUtil.setFullyAuthenticatedUser(user);
|
||||||
|
|
||||||
|
final RetryingTransactionCallback<Void> resetDisabledPathsCallback = new RetryingTransactionCallback<Void>()
|
||||||
|
{
|
||||||
|
public Void execute() throws Throwable
|
||||||
|
{
|
||||||
|
auditComponent.resetDisabledPaths(APPLICATION_TEST);
|
||||||
|
auditComponent.resetDisabledPaths(APPLICATION_ACTIONS_TEST);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
transactionService.getRetryingTransactionHelper().doInTransaction(resetDisabledPathsCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -368,4 +379,74 @@ public class AuditComponentTest extends TestCase
|
|||||||
logger.debug(sb.toString());
|
logger.debug(sb.toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test disabling of audit using audit paths
|
||||||
|
*/
|
||||||
|
public void testAudit_EnableDisableAuditPaths() throws Exception
|
||||||
|
{
|
||||||
|
Serializable valueA = new Date();
|
||||||
|
Serializable valueB = "BBB-value-here";
|
||||||
|
Serializable valueC = new Float(16.0F);
|
||||||
|
// Get a noderef
|
||||||
|
final Map<String, Serializable> parameters = new HashMap<String, Serializable>(13);
|
||||||
|
parameters.put("A", valueA);
|
||||||
|
parameters.put("B", valueB);
|
||||||
|
parameters.put("C", valueC);
|
||||||
|
// lowercase versions are not in the config
|
||||||
|
parameters.put("a", valueA);
|
||||||
|
parameters.put("b", valueB);
|
||||||
|
parameters.put("c", valueC);
|
||||||
|
|
||||||
|
Map<String, Serializable> result = auditTestAction("action-01", nodeRef, parameters);
|
||||||
|
|
||||||
|
final Map<String, Serializable> expected = new HashMap<String, Serializable>();
|
||||||
|
expected.put("/actions-test/actions/user", AuthenticationUtil.getFullyAuthenticatedUser());
|
||||||
|
expected.put("/actions-test/actions/context-node/noderef", nodeRef);
|
||||||
|
expected.put("/actions-test/actions/action-01/params/A/value", valueA);
|
||||||
|
expected.put("/actions-test/actions/action-01/params/B/value", valueB);
|
||||||
|
expected.put("/actions-test/actions/action-01/params/C/value", valueC);
|
||||||
|
|
||||||
|
// Check
|
||||||
|
checkAuditMaps(result, expected);
|
||||||
|
|
||||||
|
// Good. Now disable a path and recheck
|
||||||
|
RetryingTransactionCallback<Void> disableAuditCallback = new RetryingTransactionCallback<Void>()
|
||||||
|
{
|
||||||
|
public Void execute() throws Throwable
|
||||||
|
{
|
||||||
|
Map<String, Serializable> expectedInner = new HashMap<String, Serializable>(expected);
|
||||||
|
|
||||||
|
auditComponent.disableAudit(APPLICATION_ACTIONS_TEST, "/actions-test/actions/action-01/params/A");
|
||||||
|
expectedInner.remove("/actions-test/actions/action-01/params/A/value");
|
||||||
|
Map<String, Serializable> result = auditTestAction("action-01", nodeRef, parameters);
|
||||||
|
checkAuditMaps(result, expectedInner);
|
||||||
|
|
||||||
|
auditComponent.disableAudit(APPLICATION_ACTIONS_TEST, "/actions-test/actions/action-01/params/B");
|
||||||
|
expectedInner.remove("/actions-test/actions/action-01/params/B/value");
|
||||||
|
result = auditTestAction("action-01", nodeRef, parameters);
|
||||||
|
checkAuditMaps(result, expectedInner);
|
||||||
|
|
||||||
|
auditComponent.disableAudit(APPLICATION_ACTIONS_TEST, "/actions-test");
|
||||||
|
expectedInner.clear();
|
||||||
|
result = auditTestAction("action-01", nodeRef, parameters);
|
||||||
|
checkAuditMaps(result, expectedInner);
|
||||||
|
|
||||||
|
// Enabling something lower down should make no difference
|
||||||
|
auditComponent.enableAudit(APPLICATION_ACTIONS_TEST, "/actions-test/actions/action-01/params/B");
|
||||||
|
expectedInner.clear();
|
||||||
|
result = auditTestAction("action-01", nodeRef, parameters);
|
||||||
|
checkAuditMaps(result, expectedInner);
|
||||||
|
|
||||||
|
// Enabling the root should give back everything
|
||||||
|
auditComponent.enableAudit(APPLICATION_ACTIONS_TEST, "/actions-test");
|
||||||
|
expectedInner = new HashMap<String, Serializable>(expected);
|
||||||
|
result = auditTestAction("action-01", nodeRef, parameters);
|
||||||
|
checkAuditMaps(result, expectedInner);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
transactionService.getRetryingTransactionHelper().doInTransaction(disableAuditCallback, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -62,6 +62,8 @@ public class AuditApplication
|
|||||||
private final Map<String, DataGenerator> dataGeneratorsByName;
|
private final Map<String, DataGenerator> dataGeneratorsByName;
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private final Application application;
|
private final Application application;
|
||||||
|
private final Long applicationId;
|
||||||
|
private final Long disabledPathsId;
|
||||||
|
|
||||||
/** Derived expaned map for fast lookup */
|
/** Derived expaned map for fast lookup */
|
||||||
private Map<String, Map<String, DataExtractor>> dataExtractors = new HashMap<String, Map<String, DataExtractor>>(11);
|
private Map<String, Map<String, DataExtractor>> dataExtractors = new HashMap<String, Map<String, DataExtractor>>(11);
|
||||||
@@ -76,7 +78,9 @@ public class AuditApplication
|
|||||||
/* package */ AuditApplication(
|
/* package */ AuditApplication(
|
||||||
Map<String, DataExtractor> dataExtractorsByName,
|
Map<String, DataExtractor> dataExtractorsByName,
|
||||||
Map<String, DataGenerator> dataGeneratorsByName,
|
Map<String, DataGenerator> dataGeneratorsByName,
|
||||||
Application application)
|
Application application,
|
||||||
|
Long applicationId,
|
||||||
|
Long disabledPathsId)
|
||||||
{
|
{
|
||||||
this.dataExtractorsByName = dataExtractorsByName;
|
this.dataExtractorsByName = dataExtractorsByName;
|
||||||
this.dataGeneratorsByName = dataGeneratorsByName;
|
this.dataGeneratorsByName = dataGeneratorsByName;
|
||||||
@@ -84,6 +88,8 @@ public class AuditApplication
|
|||||||
|
|
||||||
this.applicationName = application.getName();
|
this.applicationName = application.getName();
|
||||||
this.applicationKey = application.getKey();
|
this.applicationKey = application.getKey();
|
||||||
|
this.applicationId = applicationId;
|
||||||
|
this.disabledPathsId = disabledPathsId;
|
||||||
|
|
||||||
buildAuditPaths(application);
|
buildAuditPaths(application);
|
||||||
}
|
}
|
||||||
@@ -118,6 +124,8 @@ public class AuditApplication
|
|||||||
StringBuilder sb = new StringBuilder(56);
|
StringBuilder sb = new StringBuilder(56);
|
||||||
sb.append("AuditApplication")
|
sb.append("AuditApplication")
|
||||||
.append("[ name=").append(applicationName)
|
.append("[ name=").append(applicationName)
|
||||||
|
.append(", id=").append(applicationId)
|
||||||
|
.append(", disabledPathsId=").append(disabledPathsId)
|
||||||
.append("]");
|
.append("]");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
@@ -138,6 +146,24 @@ public class AuditApplication
|
|||||||
return applicationKey;
|
return applicationKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the database ID for this application
|
||||||
|
*/
|
||||||
|
public Long getApplicationId()
|
||||||
|
{
|
||||||
|
return applicationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the property representing the set of disabled paths for the application
|
||||||
|
*
|
||||||
|
* @return Returns an ID <code>Set<String></code> of disabled paths
|
||||||
|
*/
|
||||||
|
public Long getDisabledPathsId()
|
||||||
|
{
|
||||||
|
return disabledPathsId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to check that a path is correct for this application instance
|
* Helper method to check that a path is correct for this application instance
|
||||||
*
|
*
|
||||||
|
@@ -96,14 +96,6 @@ public class AuditModelRegistry
|
|||||||
* Used to lookup the audit application java hierarchy
|
* Used to lookup the audit application java hierarchy
|
||||||
*/
|
*/
|
||||||
private final Map<String, AuditApplication> auditApplicationsByName;
|
private final Map<String, AuditApplication> auditApplicationsByName;
|
||||||
/**
|
|
||||||
* Used to lookup a reference to the application
|
|
||||||
*/
|
|
||||||
private final Map<String, Long> auditApplicationIdsByApplicationsName;
|
|
||||||
/**
|
|
||||||
* Used to lookup application disabled paths
|
|
||||||
*/
|
|
||||||
private final Map<String, Set<String>> auditDisabledPathsByApplicationsName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
@@ -119,8 +111,6 @@ public class AuditModelRegistry
|
|||||||
auditModelUrls = new HashSet<URL>(7);
|
auditModelUrls = new HashSet<URL>(7);
|
||||||
auditModels = new ArrayList<Audit>(7);
|
auditModels = new ArrayList<Audit>(7);
|
||||||
auditApplicationsByName = new HashMap<String, AuditApplication>(7);
|
auditApplicationsByName = new HashMap<String, AuditApplication>(7);
|
||||||
auditApplicationIdsByApplicationsName = new HashMap<String, Long>(7);
|
|
||||||
auditDisabledPathsByApplicationsName = new HashMap<String, Set<String>>(7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -215,7 +205,6 @@ public class AuditModelRegistry
|
|||||||
{
|
{
|
||||||
auditModels.clear();
|
auditModels.clear();
|
||||||
auditApplicationsByName.clear();
|
auditApplicationsByName.clear();
|
||||||
auditApplicationIdsByApplicationsName.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -223,7 +212,8 @@ public class AuditModelRegistry
|
|||||||
* the audit models for later retrieval. Models are loaded from the locations given by the
|
* the audit models for later retrieval. Models are loaded from the locations given by the
|
||||||
* {@link #registerModel(URL) register} methods.
|
* {@link #registerModel(URL) register} methods.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Note, the models are loaded in a new transaction.
|
* Note, the models are loaded in a new transaction, so this method can be called by any code
|
||||||
|
* at any time.
|
||||||
*/
|
*/
|
||||||
public void loadAuditModels()
|
public void loadAuditModels()
|
||||||
{
|
{
|
||||||
@@ -268,7 +258,7 @@ public class AuditModelRegistry
|
|||||||
clearCaches();
|
clearCaches();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(loadModelsCallback);
|
transactionService.getRetryingTransactionHelper().doInTransaction(loadModelsCallback, false, true);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -276,25 +266,6 @@ public class AuditModelRegistry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the ID of the persisted audit application for the given application name
|
|
||||||
*
|
|
||||||
* @param applicationName the name of the audited application
|
|
||||||
* @return the unique ID of the persisted application (<tt>null</tt> if not found)
|
|
||||||
*/
|
|
||||||
public Long getAuditApplicationId(String applicationName)
|
|
||||||
{
|
|
||||||
readLock.lock();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return auditApplicationIdsByApplicationsName.get(applicationName);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the application model for the given application name
|
* Get the application model for the given application name
|
||||||
*
|
*
|
||||||
@@ -314,25 +285,6 @@ public class AuditModelRegistry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all disabled paths for the given application name
|
|
||||||
*
|
|
||||||
* @param applicationName the name of the audited application
|
|
||||||
* @return a set of paths for which logging is disabled
|
|
||||||
*/
|
|
||||||
public Set<String> getAuditDisabledPaths(String applicationName)
|
|
||||||
{
|
|
||||||
readLock.lock();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return auditDisabledPathsByApplicationsName.get(applicationName);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unmarshalls the Audit model from the URL.
|
* Unmarshalls the Audit model from the URL.
|
||||||
*
|
*
|
||||||
@@ -552,10 +504,13 @@ public class AuditModelRegistry
|
|||||||
auditDAO.updateAuditApplicationModel(appInfo.getId(), auditModelId);
|
auditDAO.updateAuditApplicationModel(appInfo.getId(), auditModelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
AuditApplication wrapperApp = new AuditApplication(dataExtractorsByName, dataGeneratorsByName, application);
|
AuditApplication wrapperApp = new AuditApplication(
|
||||||
|
dataExtractorsByName,
|
||||||
|
dataGeneratorsByName,
|
||||||
|
application,
|
||||||
|
appInfo.getId(),
|
||||||
|
appInfo.getDisabledPathsId());
|
||||||
auditApplicationsByName.put(name, wrapperApp);
|
auditApplicationsByName.put(name, wrapperApp);
|
||||||
auditApplicationIdsByApplicationsName.put(name, appInfo.getId());
|
|
||||||
auditDisabledPathsByApplicationsName.put(name, appInfo.getDisabledPaths());
|
|
||||||
}
|
}
|
||||||
// Store the model itself
|
// Store the model itself
|
||||||
auditModels.add(audit);
|
auditModels.add(audit);
|
||||||
|
@@ -209,7 +209,6 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO
|
|||||||
* alf_audit_application
|
* alf_audit_application
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public AuditApplicationInfo getAuditApplication(String application)
|
public AuditApplicationInfo getAuditApplication(String application)
|
||||||
{
|
{
|
||||||
AuditApplicationEntity entity = getAuditApplicationByName(application);
|
AuditApplicationEntity entity = getAuditApplicationByName(application);
|
||||||
@@ -223,9 +222,7 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO
|
|||||||
appInfo.setId(entity.getId());
|
appInfo.setId(entity.getId());
|
||||||
appInfo.setname(application);
|
appInfo.setname(application);
|
||||||
appInfo.setModelId(entity.getAuditModelId());
|
appInfo.setModelId(entity.getAuditModelId());
|
||||||
// Resolve the disabled paths
|
appInfo.setDisabledPathsId(entity.getDisabledPathsId());
|
||||||
Set<String> disabledPaths = (Set<String>) propertyValueDAO.getPropertyById(entity.getDisabledPathsId());
|
|
||||||
appInfo.setDisabledPaths(disabledPaths);
|
|
||||||
// Done
|
// Done
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
@@ -252,7 +249,7 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO
|
|||||||
appInfo.setId(entity.getId());
|
appInfo.setId(entity.getId());
|
||||||
appInfo.setname(application);
|
appInfo.setname(application);
|
||||||
appInfo.setModelId(modelId);
|
appInfo.setModelId(modelId);
|
||||||
appInfo.setDisabledPaths(disabledPaths);
|
appInfo.setDisabledPathsId(disabledPathsId);
|
||||||
// Done
|
// Done
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
|
@@ -78,7 +78,7 @@ public interface AuditDAO
|
|||||||
private Long id;
|
private Long id;
|
||||||
private String name;
|
private String name;
|
||||||
private Long modelId;
|
private Long modelId;
|
||||||
private Set<String> disabledPaths;
|
private Long disabledPathsId;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
@@ -88,7 +88,7 @@ public interface AuditDAO
|
|||||||
.append("[ id=").append(id)
|
.append("[ id=").append(id)
|
||||||
.append(", name=").append(name)
|
.append(", name=").append(name)
|
||||||
.append(", modelId=").append(modelId)
|
.append(", modelId=").append(modelId)
|
||||||
.append(", disabledPaths=").append(disabledPaths)
|
.append(", disabledPathsId=").append(disabledPathsId)
|
||||||
.append("]");
|
.append("]");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
@@ -117,13 +117,13 @@ public interface AuditDAO
|
|||||||
{
|
{
|
||||||
this.modelId = modelId;
|
this.modelId = modelId;
|
||||||
}
|
}
|
||||||
public Set<String> getDisabledPaths()
|
public Long getDisabledPathsId()
|
||||||
{
|
{
|
||||||
return disabledPaths;
|
return disabledPathsId;
|
||||||
}
|
}
|
||||||
public void setDisabledPaths(Set<String> disabledPaths)
|
public void setDisabledPathsId(Long disabledPathsId)
|
||||||
{
|
{
|
||||||
this.disabledPaths = disabledPaths;
|
this.disabledPathsId = disabledPathsId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user