Merged V2.2 to HEAD

8219: Fix audit date behaviour, auto truncate all values to fit, fix retrying transaction use
         AR-1923   AWC-1637


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8486 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley 2008-03-10 16:42:56 +00:00
parent d156b449cd
commit d05655f3c7
12 changed files with 285 additions and 244 deletions

View File

@ -21,8 +21,8 @@
<property name="auditDAO">
<ref bean="auditDao"/>
</property>
<property name="auditFailedDAO">
<ref bean="auditFailedDao"/>
<property name="transactionService">
<ref bean="transactionService"/>
</property>
<property name="auditConfiguration">
<ref bean="auditConfiguration"/>
@ -66,22 +66,5 @@
</property>
</bean>
<!-- The audit DAO wapped to use another TX so we can log exceptions -->
<bean id='auditFailedDao' class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.alfresco.repo.audit.AuditDAO</value>
</property>
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref bean="auditDao" />
</property>
<property name="transactionAttributes">
<props>
<prop key="*">${server.transaction.mode.default}, PROPAGATION_REQUIRES_NEW</prop>
</props>
</property>
</bean>
</beans>

View File

@ -35,6 +35,7 @@ import org.alfresco.repo.audit.model.AuditEntry;
import org.alfresco.repo.audit.model.TrueFalseUnset;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.Auditable;
import org.alfresco.service.NotAuditable;
import org.alfresco.service.PublicService;
@ -43,13 +44,14 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.transaction.TransactionService;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* The default audit component implementation. TODO: Implement before, after and exception filtering. At the moment these filters are ignired. TODO: Respect audit internal - at the
* moment audit internal is fixed to false.
* The default audit component implementation. TODO: Implement before, after and exception filtering. At the moment
* these filters are ignired. TODO: Respect audit internal - at the moment audit internal is fixed to false.
*
* @author Andy Hind
*/
@ -79,7 +81,7 @@ public class AuditComponentImpl implements AuditComponent
private AuditDAO auditDAO;
private AuditDAO auditFailedDAO;
private TransactionService transactionService;
private AuditModel auditModel;
@ -91,7 +93,6 @@ public class AuditComponentImpl implements AuditComponent
/**
* Default constructor
*
*/
public AuditComponentImpl()
{
@ -113,7 +114,8 @@ public class AuditComponentImpl implements AuditComponent
/**
* Set the DAO for recording auditable information when no exception occurs.
* @param auditDAO
*
* @param auditDAO
*/
public void setAuditDAO(AuditDAO auditDAO)
{
@ -122,11 +124,12 @@ public class AuditComponentImpl implements AuditComponent
/**
* Set the DAO for recording failed actions - this is done in another transaction.
*
* @param auditFailedDAO
*/
public void setAuditFailedDAO(AuditDAO auditFailedDAO)
public void setTransactionService(TransactionService transactionService)
{
this.auditFailedDAO = auditFailedDAO;
this.transactionService = transactionService;
}
/**
@ -141,6 +144,7 @@ public class AuditComponentImpl implements AuditComponent
/**
* Set the helper used to identify public services
*
* @param publicServiceIdentifier
*/
public void setPublicServiceIdentifier(PublicServiceIdentifier publicServiceIdentifier)
@ -148,8 +152,9 @@ public class AuditComponentImpl implements AuditComponent
this.publicServiceIdentifier = publicServiceIdentifier;
}
/**
/**
* Set the audit model.
*
* @param auditModel
*/
public void setAuditModel(AuditModel auditModel)
@ -161,7 +166,7 @@ public class AuditComponentImpl implements AuditComponent
{
if ((auditFlag.get() == null) || (!auditFlag.get().booleanValue()))
{
if (auditModel instanceof AuditEntry && ((AuditEntry)auditModel).getEnabled() == TrueFalseUnset.TRUE)
if (auditModel instanceof AuditEntry && ((AuditEntry) auditModel).getEnabled() == TrueFalseUnset.TRUE)
{
boolean auditInternal = (auditModel.getAuditInternalServiceMethods(mi) == TrueFalseUnset.TRUE);
try
@ -217,8 +222,7 @@ public class AuditComponentImpl implements AuditComponent
{
s_logger.debug("Unannotated service method " + serviceName + "." + methodName);
}
if (method.getDeclaringClass().isInterface()
&& method.getDeclaringClass().isAnnotationPresent(PublicService.class))
if (method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAnnotationPresent(PublicService.class))
{
throw new RuntimeException("Unannotated service method " + serviceName + "." + methodName);
}
@ -249,13 +253,16 @@ public class AuditComponentImpl implements AuditComponent
/**
* Internal audit of a method invocation
* @param mi - the method to audit
*
* @param mi -
* the method to audit
* @return - the return object from the audited method
* @throws Throwable - any Throwable that can be thrown by th audtied method.
* @throws Throwable -
* any Throwable that can be thrown by th audtied method.
*/
public Object auditImpl(MethodInvocation mi) throws Throwable
{
AuditState auditInfo = new AuditState(auditConfiguration);
final AuditState auditInfo = new AuditState(auditConfiguration);
// RecordOptions recordOptions = auditModel.getAuditRecordOptions(mi);
AuditMode auditMode = AuditMode.UNSET;
try
@ -265,7 +272,15 @@ public class AuditComponentImpl implements AuditComponent
auditMode = postInvocation(auditMode, auditInfo, mi, o);
if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.SUCCESS))
{
auditDAO.audit(auditInfo);
RetryingTransactionCallback<Object> cb = new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
auditDAO.audit(auditInfo);
return null;
}
};
transactionService.getRetryingTransactionHelper().doInTransaction(cb, false, false);
}
return o;
}
@ -276,7 +291,16 @@ public class AuditComponentImpl implements AuditComponent
{
try
{
auditFailedDAO.audit(auditInfo);
RetryingTransactionCallback<Object> cb = new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
auditDAO.audit(auditInfo);
return null;
}
};
transactionService.getRetryingTransactionHelper().doInTransaction(cb, false, true);
}
catch (Throwable tt)
{
@ -288,13 +312,14 @@ public class AuditComponentImpl implements AuditComponent
}
/**
* Helper method to set auditable properties and to determine if auditing is required when an exception is caught in the audited method.
* Helper method to set auditable properties and to determine if auditing is required when an exception is caught in
* the audited method.
*
* @param auditMode
* @param auditInfo
* @param mi
* @param t
* @return - the audit mode
* @return - the audit mode
*/
private AuditMode onError(AuditMode auditMode, AuditState auditInfo, MethodInvocation mi, Throwable t)
{
@ -308,7 +333,8 @@ public class AuditComponentImpl implements AuditComponent
}
/**
* Helper method to set audited information after method invocation and to determine if auditing should take place based on the method return value.
* Helper method to set audited information after method invocation and to determine if auditing should take place
* based on the method return value.
*
* @param auditMode
* @param auditInfo
@ -355,8 +381,7 @@ public class AuditComponentImpl implements AuditComponent
else
{
s_logger.warn("Key argument is not a node, store or child assoc ref for return object on "
+ publicServiceIdentifier.getPublicServiceName(mi) + "." + mi.getMethod().getName()
+ " it is " + returnObject.getClass().getName());
+ publicServiceIdentifier.getPublicServiceName(mi) + "." + mi.getMethod().getName() + " it is " + returnObject.getClass().getName());
}
}
}
@ -373,7 +398,8 @@ public class AuditComponentImpl implements AuditComponent
}
/**
* Set auditable information and determine if auditing is required before method invocation. This would normally be based on the method arguments.
* Set auditable information and determine if auditing is required before method invocation. This would normally be
* based on the method arguments.
*
* @param auditMode
* @param auditInfo
@ -484,8 +510,7 @@ public class AuditComponentImpl implements AuditComponent
Serializable[] serArgs = new Serializable[mi.getArguments().length];
for (int i = 0; i < mi.getArguments().length; i++)
{
if ((auditable.recordable() == null)
|| (auditable.recordable().length <= i) || auditable.recordable()[i])
if ((auditable.recordable() == null) || (auditable.recordable().length <= i) || auditable.recordable()[i])
{
if (mi.getArguments()[i] == null)
{
@ -522,8 +547,7 @@ public class AuditComponentImpl implements AuditComponent
{
if (mi.getArguments().length <= position)
{
s_logger.warn("Auditable annotation on "
+ serviceName + "." + methodName + " references non existant argument");
s_logger.warn("Auditable annotation on " + serviceName + "." + methodName + " references non existant argument");
}
}
@ -532,7 +556,7 @@ public class AuditComponentImpl implements AuditComponent
*/
public void audit(String source, String description, NodeRef key, Object... args)
{
AuditState auditInfo = new AuditState(auditConfiguration);
final AuditState auditInfo = new AuditState(auditConfiguration);
// RecordOptions recordOptions = auditModel.getAuditRecordOptions(mi);
AuditMode auditMode = AuditMode.UNSET;
try
@ -540,7 +564,15 @@ public class AuditComponentImpl implements AuditComponent
auditMode = onApplicationAudit(auditMode, auditInfo, source, description, key, args);
if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.SUCCESS))
{
auditDAO.audit(auditInfo);
RetryingTransactionCallback<Object> cb = new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
auditDAO.audit(auditInfo);
return null;
}
};
transactionService.getRetryingTransactionHelper().doInTransaction(cb, false, false);
}
}
catch (Throwable t)
@ -550,7 +582,16 @@ public class AuditComponentImpl implements AuditComponent
{
try
{
auditFailedDAO.audit(auditInfo);
RetryingTransactionCallback<Object> cb = new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
auditDAO.audit(auditInfo);
return null;
}
};
transactionService.getRetryingTransactionHelper().doInTransaction(cb, false, true);
}
catch (Throwable tt)
{
@ -566,8 +607,7 @@ public class AuditComponentImpl implements AuditComponent
return auditDAO.getAuditTrail(nodeRef);
}
private AuditMode onApplicationAudit(AuditMode auditMode, AuditState auditInfo, String source, String description,
NodeRef key, Object... args)
private AuditMode onApplicationAudit(AuditMode auditMode, AuditState auditInfo, String source, String description, NodeRef key, Object... args)
{
AuditMode effectiveAuditMode = auditModel.beforeExecution(auditMode, source, description, key, args);
@ -626,8 +666,7 @@ public class AuditComponentImpl implements AuditComponent
return effectiveAuditMode;
}
private AuditMode onError(AuditMode auditMode, AuditState auditInfo, Throwable t, String source,
String description, NodeRef key, Object... args)
private AuditMode onError(AuditMode auditMode, AuditState auditInfo, Throwable t, String source, String description, NodeRef key, Object... args)
{
if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.FAIL))
{

View File

@ -124,6 +124,15 @@
audit_date.id = (select max(audit_date_2.id) from org.alfresco.repo.audit.hibernate.AuditDateImpl as audit_date_2)
</query>
<query name="audit.GetAuditDate">
select
audit_date
from
org.alfresco.repo.audit.hibernate.AuditDateImpl as audit_date
where
audit_date.id = (select max(audit_date_2.id) from org.alfresco.repo.audit.hibernate.AuditDateImpl as audit_date_2 where audit_date_2.date = :date)
</query>
<query name="audit.GetLatestAuditConfig">
select
audit_config

View File

@ -45,5 +45,5 @@ public interface AuditConfig
*
* @return
*/
public abstract long getId();
public abstract Long getId();
}

View File

@ -34,7 +34,7 @@ public class AuditConfigImpl implements AuditConfig, InitializingBean
/**
* The hibernate generated internal key.
*/
private long id;
private Long id;
/**
* The URL to the content that contains the configuration file
@ -75,7 +75,7 @@ public class AuditConfigImpl implements AuditConfig, InitializingBean
*
* @see org.alfresco.repo.audit.hibernate.AuditContig#getId()
*/
public long getId()
public Long getId()
{
return id;
}
@ -87,20 +87,11 @@ public class AuditConfigImpl implements AuditConfig, InitializingBean
*/
@SuppressWarnings("unused")
private void setId(long id)
private void setId(Long id)
{
this.id = id;
}
/**
* Helper method to get the latest audit config
*/
public static AuditConfig getLatestConfig(Session session)
{
Query query = session.getNamedQuery(HibernateAuditDAO.QUERY_LAST_AUDIT_CONFIG);
return (AuditConfig) query.uniqueResult();
}
@Override
public boolean equals(Object o)
{

View File

@ -62,7 +62,7 @@ public interface AuditDate
/**
* @return the surrogate key
*/
public abstract long getId();
public abstract Long getId();
/**
* @return the month of the year

View File

@ -42,7 +42,7 @@ public class AuditDateImpl implements AuditDate
/**
* Surrogate key
*/
private long id;
private Long id;
/**
* The date
@ -171,12 +171,12 @@ public class AuditDateImpl implements AuditDate
this.halfYear = halfYear;
}
public long getId()
public Long getId()
{
return id;
}
protected void setId(long id)
protected void setId(Long id)
{
this.id = id;
}
@ -251,14 +251,5 @@ public class AuditDateImpl implements AuditDate
{
return this.date.hashCode();
}
/**
* Helper method to get the latest audit date
*/
public static AuditDate getLatestDate(Session session)
{
Query query = session.getNamedQuery(HibernateAuditDAO.QUERY_LAST_AUDIT_DATE);
return (AuditDate) query.uniqueResult();
}
}

View File

@ -57,7 +57,7 @@ public interface AuditFact
public abstract String getHostInetAddress();
public abstract long getId();
public abstract Long getId();
public abstract String getMessage();

View File

@ -38,7 +38,7 @@ import org.hibernate.Session;
*/
public class AuditFactImpl implements AuditFact
{
private long id;
private Long id;
private AuditDate auditDate;
@ -378,12 +378,12 @@ public class AuditFactImpl implements AuditFact
*
* @see org.alfresco.repo.audit.hibernate.AuditFact#getId()
*/
public long getId()
public Long getId()
{
return id;
}
protected void setId(long id)
protected void setId(Long id)
{
this.id = id;
}
@ -587,18 +587,4 @@ public class AuditFactImpl implements AuditFact
{
this.userId = userId;
}
/**
* Helper method to get all the audit entries for a node.
*/
@SuppressWarnings("unchecked")
public static List<AuditFact> getAuditTrail(Session session, NodeRef nodeRef)
{
Query query = session.getNamedQuery(HibernateAuditDAO.QUERY_AUDIT_TRAIL);
query.setParameter(HibernateAuditDAO.QUERY_AUDIT_PROTOCOL, nodeRef.getStoreRef().getProtocol());
query.setParameter(HibernateAuditDAO.QUERY_AUDIT_STORE_ID, nodeRef.getStoreRef().getIdentifier());
query.setParameter(HibernateAuditDAO.QUERY_AUDIT_NODE_ID, nodeRef.getId());
query.setParameter(HibernateAuditDAO.QUERY_AUDIT_NODE_REF, "%"+nodeRef.toString()+"%");
return (List<AuditFact>) query.list();
}
}

View File

@ -28,7 +28,7 @@ public interface AuditSource
{
public String getApplication();
public long getId();
public Long getId();
public String getMethod();

View File

@ -33,7 +33,7 @@ public class AuditSourceImpl implements AuditSource
/**
* The surrogate key
*/
private long id;
private Long id;
/**
* The auditing application (System for method audits)
@ -65,12 +65,12 @@ public class AuditSourceImpl implements AuditSource
this.application = application;
}
public long getId()
public Long getId()
{
return id;
}
protected void setId(long id)
protected void setId(Long id)
{
this.id = id;
}
@ -95,22 +95,6 @@ public class AuditSourceImpl implements AuditSource
this.service = service;
}
public static AuditSource getApplicationSource(Session session, String application)
{
Query query = session.getNamedQuery(HibernateAuditDAO.QUERY_AUDIT_APP_SOURCE);
query.setParameter(HibernateAuditDAO.QUERY_AUDIT_APP_SOURCE_APP, application);
return (AuditSource) query.uniqueResult();
}
public static AuditSource getApplicationSource(Session session, String application, String service,
String method)
{
Query query = session.getNamedQuery(HibernateAuditDAO.QUERY_AUDIT_METHOD_SOURCE);
query.setParameter(HibernateAuditDAO.QUERY_AUDIT_APP_SOURCE_APP, application);
query.setParameter(HibernateAuditDAO.QUERY_AUDIT_APP_SOURCE_SER, service);
query.setParameter(HibernateAuditDAO.QUERY_AUDIT_APP_SOURCE_MET, method);
return (AuditSource) query.uniqueResult();
}
@Override
public boolean equals(Object o)

View File

@ -28,6 +28,7 @@ import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
@ -47,18 +48,23 @@ import org.alfresco.repo.content.ContentStore;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.TransactionalDao;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.audit.AuditInfo;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.datatype.Duration;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.EqualsHelper;
import org.alfresco.util.GUID;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.mapping.Column;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
@ -74,43 +80,39 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
*/
private static Log s_logger = LogFactory.getLog(HibernateAuditDAO.class);
public static final String QUERY_LAST_AUDIT_DATE = "audit.GetLatestAuditDate";
private static final String QUERY_LAST_AUDIT_DATE = "audit.GetLatestAuditDate";
public static final String QUERY_LAST_AUDIT_CONFIG = "audit.GetLatestAuditConfig";
private static final String QUERY_AUDIT_DATE = "audit.GetAuditDate";
public static final String QUERY_AUDIT_APP_SOURCE = "audit.GetAuditSourceByApplication";
private static final String QUERY_LAST_AUDIT_CONFIG = "audit.GetLatestAuditConfig";
public static final String QUERY_AUDIT_METHOD_SOURCE = "audit.GetAuditSourceByApplicationServiceMethod";
private static final String QUERY_AUDIT_APP_SOURCE = "audit.GetAuditSourceByApplication";
public static final String QUERY_AUDIT_APP_SOURCE_APP = "application";
private static final String QUERY_AUDIT_METHOD_SOURCE = "audit.GetAuditSourceByApplicationServiceMethod";
public static final String QUERY_AUDIT_APP_SOURCE_SER = "service";
private static final String QUERY_AUDIT_APP_SOURCE_APP = "application";
public static final String QUERY_AUDIT_APP_SOURCE_MET = "method";
private static final String QUERY_AUDIT_APP_SOURCE_SER = "service";
public static final String QUERY_AUDIT_TRAIL = "audit.GetAuditTrailForNode";
private static final String QUERY_AUDIT_APP_SOURCE_MET = "method";
public static final String QUERY_AUDIT_PROTOCOL = "protocol";
private static final String QUERY_AUDIT_TRAIL = "audit.GetAuditTrailForNode";
public static final String QUERY_AUDIT_STORE_ID = "store_id";
private static final String QUERY_AUDIT_PROTOCOL = "protocol";
public static final String QUERY_AUDIT_NODE_ID = "node_id";
private static final String QUERY_AUDIT_STORE_ID = "store_id";
public static final String QUERY_AUDIT_NODE_REF = "nodeRef";
private static final String QUERY_AUDIT_NODE_ID = "node_id";
private static final String QUERY_AUDIT_NODE_REF = "nodeRef";
private static final String QUERY_AUDIT_DATE_PARAM = "date";
/** a uuid identifying this unique instance */
private String uuid;
private ContentStore contentStore;
private ThreadLocal<AuditConfiguration> auditConfiguration = new ThreadLocal<AuditConfiguration>();
private ThreadLocal<Long> auditConfigImplId = new ThreadLocal<Long>();
private ThreadLocal<Long> auditDateImplId = new ThreadLocal<Long>();
private ThreadLocal<HashMap<SourceKey, Long>> sourceIds = new ThreadLocal<HashMap<SourceKey, Long>>();
private LocalSessionFactoryBean localSessionFactory;
public HibernateAuditDAO()
@ -181,7 +183,6 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
if (args != null)
{
int length;
switch (args.length)
{
default:
@ -199,25 +200,26 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
}
}
auditFact.setClientInetAddress(auditInfo.getClientAddress() == null ? null : auditInfo.getClientAddress().toString());
auditFact.setClientInetAddress(getStringOrNull(auditInfo.getClientAddress(), getColumnLength("org.alfresco.repo.audit.hibernate.AuditFactImpl", "clientInetAddress")));
auditFact.setDate(auditInfo.getDate());
auditFact.setException(auditInfo.getThrowable() == null ? null : auditInfo.getThrowable().getMessage());
auditFact.setException(getStringOrNull((auditInfo.getThrowable() == null ? null : auditInfo.getThrowable().getMessage()), getColumnLength(
"org.alfresco.repo.audit.hibernate.AuditFactImpl", "exception")));
auditFact.setFail(auditInfo.isFail());
auditFact.setFiltered(auditInfo.isFiltered());
auditFact.setHostInetAddress(auditInfo.getHostAddress() == null ? null : auditInfo.getHostAddress().toString());
auditFact.setMessage(auditInfo.getMessage());
auditFact.setNodeUUID(auditInfo.getKeyGUID());
auditFact.setPath(auditInfo.getPath());
auditFact.setReturnValue(auditInfo.getReturnObject() == null ? null : auditInfo.getReturnObject().toString());
auditFact.setHostInetAddress(getStringOrNull(auditInfo.getHostAddress(), getColumnLength("org.alfresco.repo.audit.hibernate.AuditFactImpl", "hostInetAddress")));
auditFact.setMessage(getStringOrNull(auditInfo.getMessage(), getColumnLength("org.alfresco.repo.audit.hibernate.AuditFactImpl", "message")));
auditFact.setNodeUUID(getStringOrNull(auditInfo.getKeyGUID(), getColumnLength("org.alfresco.repo.audit.hibernate.AuditFactImpl", "nodeUUID")));
auditFact.setPath(getStringOrNull(auditInfo.getPath(), getColumnLength("org.alfresco.repo.audit.hibernate.AuditFactImpl", "path")));
auditFact.setReturnValue(getStringOrNull(auditInfo.getReturnObject(), getColumnLength("org.alfresco.repo.audit.hibernate.AuditFactImpl", "returnValue")));
// auditFact.setSerialisedURL()
auditFact.setSessionId(auditInfo.getSessionId());
auditFact.setSessionId(getStringOrNull(auditInfo.getSessionId(), getColumnLength("org.alfresco.repo.audit.hibernate.AuditFactImpl", "sessionId")));
if (auditInfo.getKeyStore() != null)
{
auditFact.setStoreId(auditInfo.getKeyStore().getIdentifier());
auditFact.setStoreProtocol(auditInfo.getKeyStore().getProtocol());
auditFact.setStoreId(getStringOrNull(auditInfo.getKeyStore().getIdentifier(), getColumnLength("org.alfresco.repo.audit.hibernate.AuditFactImpl", "storeId")));
auditFact.setStoreProtocol(getStringOrNull(auditInfo.getKeyStore().getProtocol(), getColumnLength("org.alfresco.repo.audit.hibernate.AuditFactImpl", "storeProtocol")));
}
auditFact.setTransactionId(auditInfo.getTxId());
auditFact.setUserId(auditInfo.getUserIdentifier());
auditFact.setTransactionId(getStringOrNull(auditInfo.getTxId(), getColumnLength("org.alfresco.repo.audit.hibernate.AuditFactImpl", "transactionId")));
auditFact.setUserId(getStringOrNull(auditInfo.getUserIdentifier(), getColumnLength("org.alfresco.repo.audit.hibernate.AuditFactImpl", "userId")));
// Save
getSession().save(auditFact);
@ -235,7 +237,7 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
}
if (s_logger.isDebugEnabled())
{
s_logger.debug(entityName + " "+propertyName+ " is of length " + length);
s_logger.debug(entityName + " " + propertyName + " is of length " + length);
}
return length;
}
@ -251,7 +253,7 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
try
{
String answer = o.toString();
if((size > -1) && (answer.length() > size))
if ((size > -1) && (answer.length() > size))
{
answer = answer.substring(0, size);
}
@ -260,7 +262,7 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
catch (Throwable t)
{
String answer = "Throwable in toString implementation for " + o.getClass() + " was " + t.getMessage();
if((size > -1) && (answer.length() > size))
if ((size > -1) && (answer.length() > size))
{
answer = answer.substring(0, size);
}
@ -269,54 +271,42 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
}
}
private AuditSource getAuditSource(AuditState auditInfo)
private AuditSource getAuditSource(final AuditState auditInfo)
{
AuditSource auditSourceImpl;
SourceKey sourceKey = new SourceKey(auditInfo.getAuditApplication(), auditInfo.getAuditService(), auditInfo.getAuditMethod());
if (sourceIds.get() == null)
{
sourceIds.set(new HashMap<SourceKey, Long>());
}
Long id = sourceIds.get().get(sourceKey);
if (id != null)
{
auditSourceImpl = (AuditSource) getSession().get(AuditSourceImpl.class, id.longValue());
if (auditSourceImpl != null)
{
return auditSourceImpl;
}
}
AuditSource auditSourceImpl;
if ((auditInfo.getAuditService() != null)
&& (auditInfo.getAuditService().length() > 0) && (auditInfo.getAuditMethod() != null) && (auditInfo.getAuditMethod().length() > 0))
{
auditSourceImpl = AuditSourceImpl.getApplicationSource(getSession(), auditInfo.getAuditApplication(), auditInfo.getAuditService(), auditInfo.getAuditMethod());
auditSourceImpl = queryApplicationSource(auditInfo.getAuditApplication(), auditInfo.getAuditService(), auditInfo.getAuditMethod());
if (auditSourceImpl == null)
{
auditSourceImpl = new AuditSourceImpl();
auditSourceImpl.setApplication(auditInfo.getAuditApplication());
auditSourceImpl.setService(auditInfo.getAuditService());
auditSourceImpl.setMethod(auditInfo.getAuditMethod());
getSession().save(auditSourceImpl);
Long id = (Long) getSession().save(auditSourceImpl);
}
}
else
{
auditSourceImpl = AuditSourceImpl.getApplicationSource(getSession(), auditInfo.getAuditApplication());
auditSourceImpl = queryApplicationSource(auditInfo.getAuditApplication());
if (auditSourceImpl == null)
{
auditSourceImpl = new AuditSourceImpl();
auditSourceImpl.setApplication(auditInfo.getAuditApplication());
getSession().save(auditSourceImpl);
Long id = (Long) getSession().save(auditSourceImpl);
}
}
sourceIds.get().put(sourceKey, Long.valueOf(auditSourceImpl.getId()));
return auditSourceImpl;
}
private AuditDate getAuditDate(AuditState auditInfo)
private AuditDate getAuditDate(final AuditState auditInfo)
{
Calendar cal = GregorianCalendar.getInstance();
cal.setTime(auditInfo.getDate());
cal.set(Calendar.MILLISECOND, 0);
@ -326,99 +316,96 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
Date required = cal.getTime();
AuditDate auditDate;
if (auditDateImplId.get() == null)
auditDate = queryLatestDate(required);
if (auditDate == null)
{
auditDate = AuditDateImpl.getLatestDate(getSession());
auditDate = queryLatestDate();
if (auditDate == null)
{
// The first entry ever so we just make it
auditDate = new AuditDateImpl(auditInfo.getDate());
getSession().save(auditDate);
Long id = (Long) getSession().save(auditDate);
}
else
{
if (required.compareTo(auditDate.getDate()) < 0)
{
auditDate = new AuditDateImpl(required);
Long id = (Long) getSession().save(auditDate);
}
else if (required.compareTo(auditDate.getDate()) == 0)
{
// no action
}
else
{
while (!required.equals(auditDate.getDate()))
{
Date nextDate = Duration.add(auditDate.getDate(), new Duration("P1D"));
auditDate = new AuditDateImpl(nextDate);
Long id = (Long) getSession().save(auditDate);
}
}
}
auditDateImplId.set(Long.valueOf(auditDate.getId()));
}
else
{
auditDate = (AuditDate) getSession().get(AuditDateImpl.class, auditDateImplId.get().longValue());
if ((auditDate == null) || (!required.equals(auditDate.getDate())))
{
auditDate = AuditDateImpl.getLatestDate(getSession());
if (auditDate == null)
{
// The first entry ever so we just make it
auditDate = new AuditDateImpl(auditInfo.getDate());
getSession().save(auditDate);
}
auditDateImplId.set(Long.valueOf(auditDate.getId()));
}
}
while (!required.equals(auditDate.getDate()))
{
Date nextDate = Duration.add(auditDate.getDate(), new Duration("P1D"));
auditDate = new AuditDateImpl(nextDate);
getSession().save(auditDate);
auditDateImplId.set(Long.valueOf(auditDate.getId()));
// no action
}
return auditDate;
}
private AuditConfig getAuditConfig(AuditState auditInfo)
private AuditConfig getAuditConfig(final AuditState auditInfo)
{
AuditConfig auditConfig;
if ((auditConfiguration.get() == null) || (auditConfiguration.get() != auditInfo.getAuditConfiguration()))
auditConfig = queryLatestConfig(getSession());
if (auditConfig == null)
{
auditConfig = AuditConfigImpl.getLatestConfig(getSession());
if (auditConfig == null)
auditConfig = createNewAuditConfigImpl(auditInfo);
}
else
{
InputStream current = new BufferedInputStream(auditInfo.getAuditConfiguration().getInputStream());
ContentReader reader = contentStore.getReader(auditConfig.getConfigURL());
reader.setMimetype(MimetypeMap.MIMETYPE_XML);
reader.setEncoding("UTF-8");
InputStream last = new BufferedInputStream(reader.getContentInputStream());
int currentValue = -2;
int lastValue = -2;
try
{
while ((currentValue != -1) && (lastValue != -1) && (currentValue == lastValue))
{
currentValue = current.read();
lastValue = last.read();
}
}
catch (IOException e)
{
throw new AlfrescoRuntimeException("Failed to read and validate current audit configuration against the last", e);
}
if (currentValue != lastValue)
{
// Files are different - require a new entry
auditConfig = createNewAuditConfigImpl(auditInfo);
}
else
{
InputStream current = new BufferedInputStream(auditInfo.getAuditConfiguration().getInputStream());
ContentReader reader = contentStore.getReader(auditConfig.getConfigURL());
reader.setMimetype(MimetypeMap.MIMETYPE_XML);
reader.setEncoding("UTF-8");
InputStream last = new BufferedInputStream(reader.getContentInputStream());
int currentValue = -2;
int lastValue = -2;
try
{
while ((currentValue != -1) && (lastValue != -1) && (currentValue == lastValue))
{
currentValue = current.read();
lastValue = last.read();
// No change
}
}
}
}
catch (IOException e)
{
throw new AlfrescoRuntimeException("Failed to read and validate current audit configuration against the last", e);
}
if (currentValue != lastValue)
{
// Files are different - require a new entry
auditConfig = createNewAuditConfigImpl(auditInfo);
}
else
{
// No change
}
}
auditConfigImplId.set(Long.valueOf(auditConfig.getId()));
auditConfiguration.set(auditInfo.getAuditConfiguration());
}
else
{
auditConfig = (AuditConfig) getSession().get(AuditConfigImpl.class, auditConfigImplId.get().longValue());
if (auditConfig == null)
{
auditConfig = createNewAuditConfigImpl(auditInfo);
}
}
return auditConfig;
}
private AuditConfigImpl createNewAuditConfigImpl(AuditState auditInfo)
private AuditConfig createNewAuditConfigImpl(final AuditState auditInfo)
{
AuditConfigImpl auditConfig = new AuditConfigImpl();
InputStream is = new BufferedInputStream(auditInfo.getAuditConfiguration().getInputStream());
@ -429,6 +416,7 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
String contentUrl = writer.getContentUrl();
auditConfig.setConfigURL(contentUrl);
getSession().save(auditConfig);
return auditConfig;
}
@ -544,7 +532,7 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
{
return Collections.<AuditInfo> emptyList();
}
List<? extends AuditFact> internalTrail = AuditFactImpl.getAuditTrail(getSession(), nodeRef);
List<? extends AuditFact> internalTrail = queryAuditTrail(nodeRef);
ArrayList<AuditInfo> answer = new ArrayList<AuditInfo>(internalTrail.size());
for (AuditFact auditFact : internalTrail)
@ -555,4 +543,74 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
return answer;
}
/**
* Helper method to get the latest audit config
*/
public static AuditConfig queryLatestConfig(Session session)
{
Query query = session.getNamedQuery(QUERY_LAST_AUDIT_CONFIG);
return (AuditConfig) query.uniqueResult();
}
/**
* Helper method to get the latest audit date
*/
public AuditDate queryLatestDate()
{
Query query = getSession().getNamedQuery(QUERY_LAST_AUDIT_DATE);
return (AuditDate) query.uniqueResult();
}
/**
* Helper method to get all the audit entries for a node.
*/
@SuppressWarnings("unchecked")
public List<AuditFact> queryAuditTrail(NodeRef nodeRef)
{
Query query = getSession().getNamedQuery(QUERY_AUDIT_TRAIL);
query.setParameter(QUERY_AUDIT_PROTOCOL, nodeRef.getStoreRef().getProtocol());
query.setParameter(QUERY_AUDIT_STORE_ID, nodeRef.getStoreRef().getIdentifier());
query.setParameter(QUERY_AUDIT_NODE_ID, nodeRef.getId());
query.setParameter(QUERY_AUDIT_NODE_REF, "%" + nodeRef.toString() + "%");
return (List<AuditFact>) query.list();
}
/**
* Helper method to get the application source
*
* @param application
* @return
*/
public AuditSource queryApplicationSource(String application)
{
Query query = getSession().getNamedQuery(QUERY_AUDIT_APP_SOURCE);
query.setParameter(QUERY_AUDIT_APP_SOURCE_APP, application);
return (AuditSource) query.uniqueResult();
}
/**
* Helper method to get the application source
*
* @param application
* @return
*/
public AuditSource queryApplicationSource(String application, String service, String method)
{
Query query = getSession().getNamedQuery(HibernateAuditDAO.QUERY_AUDIT_METHOD_SOURCE);
query.setParameter(QUERY_AUDIT_APP_SOURCE_APP, application);
query.setParameter(QUERY_AUDIT_APP_SOURCE_SER, service);
query.setParameter(QUERY_AUDIT_APP_SOURCE_MET, method);
return (AuditSource) query.uniqueResult();
}
/**
* Helper method to get the latest audit date
*/
public AuditDate queryLatestDate(Date date)
{
Query query = getSession().getNamedQuery(HibernateAuditDAO.QUERY_AUDIT_DATE);
query.setParameter(QUERY_AUDIT_DATE_PARAM, date);
return (AuditDate) query.uniqueResult();
}
}