diff --git a/config/alfresco/audit-services-context.xml b/config/alfresco/audit-services-context.xml index 96ab0a584e..2b889fa114 100644 --- a/config/alfresco/audit-services-context.xml +++ b/config/alfresco/audit-services-context.xml @@ -21,8 +21,8 @@ - - + + @@ -66,22 +66,5 @@ - - - - - org.alfresco.repo.audit.AuditDAO - - - - - - - - - - ${server.transaction.mode.default}, PROPAGATION_REQUIRES_NEW - - - + \ No newline at end of file diff --git a/source/java/org/alfresco/repo/audit/AuditComponentImpl.java b/source/java/org/alfresco/repo/audit/AuditComponentImpl.java index 4b2b946002..3060830b70 100644 --- a/source/java/org/alfresco/repo/audit/AuditComponentImpl.java +++ b/source/java/org/alfresco/repo/audit/AuditComponentImpl.java @@ -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 cb = new RetryingTransactionCallback() + { + 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 cb = new RetryingTransactionCallback() + { + 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 cb = new RetryingTransactionCallback() + { + 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 cb = new RetryingTransactionCallback() + { + 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)) { diff --git a/source/java/org/alfresco/repo/audit/hibernate/Audit.hbm.xml b/source/java/org/alfresco/repo/audit/hibernate/Audit.hbm.xml index 5b9e10aaea..a8db04e9b4 100644 --- a/source/java/org/alfresco/repo/audit/hibernate/Audit.hbm.xml +++ b/source/java/org/alfresco/repo/audit/hibernate/Audit.hbm.xml @@ -124,6 +124,15 @@ audit_date.id = (select max(audit_date_2.id) from org.alfresco.repo.audit.hibernate.AuditDateImpl as audit_date_2) + + 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) + + select audit_config diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditConfig.java b/source/java/org/alfresco/repo/audit/hibernate/AuditConfig.java index 9c35f5e170..afecb4a163 100644 --- a/source/java/org/alfresco/repo/audit/hibernate/AuditConfig.java +++ b/source/java/org/alfresco/repo/audit/hibernate/AuditConfig.java @@ -45,5 +45,5 @@ public interface AuditConfig * * @return */ - public abstract long getId(); + public abstract Long getId(); } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditConfigImpl.java b/source/java/org/alfresco/repo/audit/hibernate/AuditConfigImpl.java index b0e0320db2..6c9ebad9b4 100644 --- a/source/java/org/alfresco/repo/audit/hibernate/AuditConfigImpl.java +++ b/source/java/org/alfresco/repo/audit/hibernate/AuditConfigImpl.java @@ -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) { diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditDate.java b/source/java/org/alfresco/repo/audit/hibernate/AuditDate.java index fd6c3009af..a4b531c8a8 100644 --- a/source/java/org/alfresco/repo/audit/hibernate/AuditDate.java +++ b/source/java/org/alfresco/repo/audit/hibernate/AuditDate.java @@ -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 diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditDateImpl.java b/source/java/org/alfresco/repo/audit/hibernate/AuditDateImpl.java index 7107b053b7..0c9cb9561a 100644 --- a/source/java/org/alfresco/repo/audit/hibernate/AuditDateImpl.java +++ b/source/java/org/alfresco/repo/audit/hibernate/AuditDateImpl.java @@ -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(); - } } diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditFact.java b/source/java/org/alfresco/repo/audit/hibernate/AuditFact.java index 810a43dc60..d55ccc1249 100644 --- a/source/java/org/alfresco/repo/audit/hibernate/AuditFact.java +++ b/source/java/org/alfresco/repo/audit/hibernate/AuditFact.java @@ -57,7 +57,7 @@ public interface AuditFact public abstract String getHostInetAddress(); - public abstract long getId(); + public abstract Long getId(); public abstract String getMessage(); diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditFactImpl.java b/source/java/org/alfresco/repo/audit/hibernate/AuditFactImpl.java index 4b7102fe5c..6e38d6d9fb 100644 --- a/source/java/org/alfresco/repo/audit/hibernate/AuditFactImpl.java +++ b/source/java/org/alfresco/repo/audit/hibernate/AuditFactImpl.java @@ -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 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) query.list(); - } } diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditSource.java b/source/java/org/alfresco/repo/audit/hibernate/AuditSource.java index a5405ebdd2..4a3b172d6f 100644 --- a/source/java/org/alfresco/repo/audit/hibernate/AuditSource.java +++ b/source/java/org/alfresco/repo/audit/hibernate/AuditSource.java @@ -28,7 +28,7 @@ public interface AuditSource { public String getApplication(); - public long getId(); + public Long getId(); public String getMethod(); diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditSourceImpl.java b/source/java/org/alfresco/repo/audit/hibernate/AuditSourceImpl.java index bfc2f8b087..9568e7a4dc 100644 --- a/source/java/org/alfresco/repo/audit/hibernate/AuditSourceImpl.java +++ b/source/java/org/alfresco/repo/audit/hibernate/AuditSourceImpl.java @@ -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) diff --git a/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java b/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java index da476c0fd5..f293011fac 100644 --- a/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java +++ b/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java @@ -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 = new ThreadLocal(); - - private ThreadLocal auditConfigImplId = new ThreadLocal(); - - private ThreadLocal auditDateImplId = new ThreadLocal(); - - private ThreadLocal> sourceIds = new ThreadLocal>(); - 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()); - } - 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. emptyList(); } - List internalTrail = AuditFactImpl.getAuditTrail(getSession(), nodeRef); + List internalTrail = queryAuditTrail(nodeRef); ArrayList answer = new ArrayList(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 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) 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(); + } + }