mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-09-17 14:21:39 +00:00
[ACS-9736] Add deflating of audit values and intecepting them into audit record
This commit is contained in:
@@ -48,7 +48,6 @@ import org.alfresco.repo.audit.model.AuditModelRegistryImpl;
|
|||||||
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.domain.propval.PropertyValueDAO;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
|
||||||
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;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
@@ -73,8 +72,8 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
{
|
{
|
||||||
private static final String INBOUND_LOGGER = "org.alfresco.repo.audit.inbound";
|
private static final String INBOUND_LOGGER = "org.alfresco.repo.audit.inbound";
|
||||||
|
|
||||||
private static Log logger = LogFactory.getLog(AuditComponentImpl.class);
|
private static final Log logger = LogFactory.getLog(AuditComponentImpl.class);
|
||||||
private static Log loggerInbound = LogFactory.getLog(INBOUND_LOGGER);
|
private static final Log loggerInbound = LogFactory.getLog(INBOUND_LOGGER);
|
||||||
|
|
||||||
private AuditModelRegistryImpl auditModelRegistry;
|
private AuditModelRegistryImpl auditModelRegistry;
|
||||||
private PropertyValueDAO propertyValueDAO;
|
private PropertyValueDAO propertyValueDAO;
|
||||||
@@ -221,7 +220,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
public int deleteAuditEntries(List<Long> auditEntryIds)
|
public int deleteAuditEntries(List<Long> auditEntryIds)
|
||||||
{
|
{
|
||||||
// Shortcut, if necessary
|
// Shortcut, if necessary
|
||||||
if (auditEntryIds.size() == 0)
|
if (auditEntryIds.isEmpty())
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -240,7 +239,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
{
|
{
|
||||||
Long disabledPathsId = application.getDisabledPathsId();
|
Long disabledPathsId = application.getDisabledPathsId();
|
||||||
Set<String> disabledPaths = (Set<String>) propertyValueDAO.getPropertyById(disabledPathsId);
|
Set<String> disabledPaths = (Set<String>) propertyValueDAO.getPropertyById(disabledPathsId);
|
||||||
return new HashSet<String>(disabledPaths);
|
return new HashSet<>(disabledPaths);
|
||||||
}
|
}
|
||||||
catch (Throwable e)
|
catch (Throwable e)
|
||||||
{
|
{
|
||||||
@@ -315,7 +314,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
{
|
{
|
||||||
PathMapper pathMapper = auditModelRegistry.getAuditPathMapper();
|
PathMapper pathMapper = auditModelRegistry.getAuditPathMapper();
|
||||||
Set<String> mappedPaths = pathMapper.getMappedPathsWithPartialMatch(path);
|
Set<String> mappedPaths = pathMapper.getMappedPathsWithPartialMatch(path);
|
||||||
return loggerInbound.isDebugEnabled() || mappedPaths.size() > 0;
|
return loggerInbound.isDebugEnabled() || !mappedPaths.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -352,7 +351,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
|
|
||||||
// Check if there are any entries that match or supercede the given path
|
// Check if there are any entries that match or supercede the given path
|
||||||
String disablingPath = null;
|
String disablingPath = null;
|
||||||
;
|
|
||||||
for (String disabledPath : disabledPaths)
|
for (String disabledPath : disabledPaths)
|
||||||
{
|
{
|
||||||
if (path.startsWith(disabledPath))
|
if (path.startsWith(disabledPath))
|
||||||
@@ -579,7 +578,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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<>(values.size() * 2);
|
||||||
for (Map.Entry<String, Serializable> entry : values.entrySet())
|
for (Map.Entry<String, Serializable> entry : values.entrySet())
|
||||||
{
|
{
|
||||||
String pathElement = entry.getKey();
|
String pathElement = entry.getKey();
|
||||||
@@ -602,13 +601,10 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
case TXN_NONE:
|
case TXN_NONE:
|
||||||
case TXN_READ_ONLY:
|
case TXN_READ_ONLY:
|
||||||
// New transaction
|
// New transaction
|
||||||
RetryingTransactionCallback<Map<String, Serializable>> callback = new RetryingTransactionCallback<Map<String, Serializable>>() {
|
RetryingTransactionCallback<Map<String, Serializable>> callback = () -> {
|
||||||
public Map<String, Serializable> execute() throws Throwable
|
Map<String, Serializable> recordedAuditValues = recordAuditValuesImpl(mappedValues);
|
||||||
{
|
auditRecordReporter.reportAuditRecord(createAuditRecord(recordedAuditValues, true));
|
||||||
Map<String, Serializable> recordedAuditValues = recordAuditValuesImpl(mappedValues);
|
return recordedAuditValues;
|
||||||
auditRecordReporter.reportAuditRecord(createAuditRecord(recordedAuditValues, true));
|
|
||||||
return recordedAuditValues;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
|
RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
|
||||||
txnHelper.setForceWritable(true);
|
txnHelper.setForceWritable(true);
|
||||||
@@ -628,7 +624,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
public Map<String, Serializable> recordAuditValuesImpl(Map<String, Serializable> mappedValues)
|
public Map<String, Serializable> recordAuditValuesImpl(Map<String, Serializable> mappedValues)
|
||||||
{
|
{
|
||||||
// Group the values by root path
|
// Group the values by root path
|
||||||
Map<String, Map<String, Serializable>> mappedValuesByRootKey = new HashMap<String, Map<String, Serializable>>();
|
Map<String, Map<String, Serializable>> mappedValuesByRootKey = new HashMap<>();
|
||||||
for (Map.Entry<String, Serializable> entry : mappedValues.entrySet())
|
for (Map.Entry<String, Serializable> entry : mappedValues.entrySet())
|
||||||
{
|
{
|
||||||
String path = entry.getKey();
|
String path = entry.getKey();
|
||||||
@@ -636,7 +632,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
Map<String, Serializable> rootKeyMappedValues = mappedValuesByRootKey.get(rootKey);
|
Map<String, Serializable> rootKeyMappedValues = mappedValuesByRootKey.get(rootKey);
|
||||||
if (rootKeyMappedValues == null)
|
if (rootKeyMappedValues == null)
|
||||||
{
|
{
|
||||||
rootKeyMappedValues = new HashMap<String, Serializable>(7);
|
rootKeyMappedValues = new HashMap<>(7);
|
||||||
mappedValuesByRootKey.put(rootKey, rootKeyMappedValues);
|
mappedValuesByRootKey.put(rootKey, rootKeyMappedValues);
|
||||||
}
|
}
|
||||||
rootKeyMappedValues.put(path, entry.getValue());
|
rootKeyMappedValues.put(path, entry.getValue());
|
||||||
@@ -704,7 +700,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if there is anything to audit
|
// Check if there is anything to audit
|
||||||
if (values.size() == 0)
|
if (values.isEmpty())
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
@@ -737,12 +733,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
Map<String, Serializable> auditData = generateData(generators);
|
Map<String, Serializable> auditData = generateData(generators);
|
||||||
|
|
||||||
// Now extract values
|
// Now extract values
|
||||||
Map<String, Serializable> extractedData = AuthenticationUtil.runAs(new RunAsWork<Map<String, Serializable>>() {
|
Map<String, Serializable> extractedData = AuthenticationUtil.runAs(() -> extractData(application, values), AuthenticationUtil.getSystemUserName());
|
||||||
public Map<String, Serializable> doWork() throws Exception
|
|
||||||
{
|
|
||||||
return extractData(application, values);
|
|
||||||
}
|
|
||||||
}, AuthenticationUtil.getSystemUserName());
|
|
||||||
|
|
||||||
// Combine extracted and generated values (extracted data takes precedence)
|
// Combine extracted and generated values (extracted data takes precedence)
|
||||||
auditData.putAll(extractedData);
|
auditData.putAll(extractedData);
|
||||||
@@ -910,7 +901,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
*/
|
*/
|
||||||
private Map<String, Serializable> generateData(Map<String, DataGenerator> generators)
|
private Map<String, Serializable> generateData(Map<String, DataGenerator> generators)
|
||||||
{
|
{
|
||||||
Map<String, Serializable> newData = new HashMap<String, Serializable>(generators.size() + 5);
|
Map<String, Serializable> newData = new HashMap<>(generators.size() + 5);
|
||||||
for (Map.Entry<String, DataGenerator> entry : generators.entrySet())
|
for (Map.Entry<String, DataGenerator> entry : generators.entrySet())
|
||||||
{
|
{
|
||||||
String path = entry.getKey();
|
String path = entry.getKey();
|
||||||
@@ -937,8 +928,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
|
|
||||||
private AuditRecord createAuditRecord(Map<String, ?> auditData, boolean inTransaction)
|
private AuditRecord createAuditRecord(Map<String, ?> auditData, boolean inTransaction)
|
||||||
{
|
{
|
||||||
AuditRecord.Builder builder = new AuditRecord.Builder();
|
AuditRecord.Builder builder = AuditRecordUtils.generateAuditRecordBuilder(auditData);
|
||||||
builder.setAuditData(auditData);
|
|
||||||
builder.setInTransaction(inTransaction);
|
builder.setInTransaction(inTransaction);
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
@@ -31,11 +31,13 @@ import java.util.Map;
|
|||||||
public class AuditRecord
|
public class AuditRecord
|
||||||
{
|
{
|
||||||
private final boolean inTransaction;
|
private final boolean inTransaction;
|
||||||
|
private final String auditApplicationId;
|
||||||
private final ZonedDateTime createdAt;
|
private final ZonedDateTime createdAt;
|
||||||
private final Map<String, ?> auditData;
|
private final Map<String, ?> auditData;
|
||||||
|
|
||||||
public AuditRecord(Builder builder)
|
public AuditRecord(Builder builder)
|
||||||
{
|
{
|
||||||
|
this.auditApplicationId = builder.auditApplicationId;
|
||||||
this.inTransaction = builder.inTransaction;
|
this.inTransaction = builder.inTransaction;
|
||||||
this.auditData = builder.auditData;
|
this.auditData = builder.auditData;
|
||||||
this.createdAt = ZonedDateTime.now();
|
this.createdAt = ZonedDateTime.now();
|
||||||
@@ -46,6 +48,11 @@ public class AuditRecord
|
|||||||
return inTransaction;
|
return inTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAuditApplicationId()
|
||||||
|
{
|
||||||
|
return auditApplicationId;
|
||||||
|
}
|
||||||
|
|
||||||
public ZonedDateTime getCreatedAt()
|
public ZonedDateTime getCreatedAt()
|
||||||
{
|
{
|
||||||
return createdAt;
|
return createdAt;
|
||||||
@@ -63,9 +70,16 @@ public class AuditRecord
|
|||||||
|
|
||||||
public static class Builder
|
public static class Builder
|
||||||
{
|
{
|
||||||
|
private String auditApplicationId;
|
||||||
private boolean inTransaction;
|
private boolean inTransaction;
|
||||||
private Map<String, ?> auditData;
|
private Map<String, ?> auditData;
|
||||||
|
|
||||||
|
public Builder setAuditApplicationId(String auditApplicationId)
|
||||||
|
{
|
||||||
|
this.auditApplicationId = auditApplicationId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder setInTransaction(boolean inTransaction)
|
public Builder setInTransaction(boolean inTransaction)
|
||||||
{
|
{
|
||||||
this.inTransaction = inTransaction;
|
this.inTransaction = inTransaction;
|
||||||
|
@@ -0,0 +1,42 @@
|
|||||||
|
package org.alfresco.repo.audit;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
|
||||||
|
public class AuditRecordUtils
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This method will generate {@link AuditRecord#builder()} from provided structured audit data. Provided data will be translated from `key - value` structure to json structure. Generated builder will be preloaded with {@link AuditRecord#auditApplicationId} and {@link AuditRecord#auditData}
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* represent `key - value` structured map that contains audit data.
|
||||||
|
* @return preloaded {@link AuditRecord#builder()}.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static AuditRecord.Builder generateAuditRecordBuilder(Map<String, ?> data)
|
||||||
|
{
|
||||||
|
var auditRecordBuilder = AuditRecord.builder();
|
||||||
|
|
||||||
|
var rootNode = new HashMap<String, Serializable>();
|
||||||
|
data.forEach((k, v) -> {
|
||||||
|
var keys = k.split("/");
|
||||||
|
auditRecordBuilder.setAuditApplicationId(keys[0]);
|
||||||
|
var current = rootNode;
|
||||||
|
for (int i = 1; i < keys.length - 1; i++)
|
||||||
|
{
|
||||||
|
if (!current.containsKey(keys[i]) || !(current.get(keys[i]) instanceof ObjectNode))
|
||||||
|
{
|
||||||
|
current.put(keys[i], new HashMap<String, Serializable>());
|
||||||
|
}
|
||||||
|
current = (HashMap<String, Serializable>) current.get(keys[i]);
|
||||||
|
}
|
||||||
|
current.put(keys[keys.length - 1], v.toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
auditRecordBuilder.setAuditData(rootNode);
|
||||||
|
return auditRecordBuilder;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user