mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Added key-value audit query
- Currently supports lookups on string values (RM use-case) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@16133 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -125,53 +125,6 @@
|
||||
join alf_audit_entry entry on (entry.audit_app_id = app.id)
|
||||
join alf_prop_value user_pv on (user_pv.id = entry.audit_user_id)
|
||||
join alf_prop_string_value user_sv on (user_sv.id = user_pv.long_value and user_pv.persisted_type = 3)
|
||||
<dynamic prepend="where">
|
||||
<isNotNull prepend="and" property="auditAppNameShort">
|
||||
app_sv.string_end_lower = #auditAppNameShort# and
|
||||
app_sv.string_crc = #auditAppNameCrc#
|
||||
</isNotNull>
|
||||
<isNotNull prepend="and" property="auditUserShort">
|
||||
user_sv.string_end_lower = #auditUserShort# and
|
||||
user_sv.string_crc = #auditUserCrc#
|
||||
</isNotNull>
|
||||
<isNotNull prepend="and" property="auditFromTime">
|
||||
<![CDATA[entry.audit_time >= #auditFromTime#]]>
|
||||
</isNotNull>
|
||||
<isNotNull prepend="and" property="auditToTime">
|
||||
<![CDATA[entry.audit_time < #auditToTime#]]>
|
||||
</isNotNull>
|
||||
</dynamic>
|
||||
order by
|
||||
entry.id
|
||||
</select>
|
||||
|
||||
<!-- Get audit entries -->
|
||||
<!-- TODO: Use compound parameters for string searching, possibly namespaced from propval -->
|
||||
<!-- TODO: Use compound result map for audit values -->
|
||||
<select id="select_AuditEntriesWithValues" parameterClass="AuditQueryParameters" resultMap="result_AuditQueryAllValues">
|
||||
select
|
||||
entry.id as audit_entry_id,
|
||||
user_sv.string_value as audit_user,
|
||||
app_sv.string_value as audit_app_name,
|
||||
entry.audit_time as audit_time,
|
||||
entry.audit_values_id as audit_values_id,
|
||||
|
||||
cl.root_prop_id, cl.current_prop_id, cl.value_prop_id, cl.key_prop_id,
|
||||
v.actual_type_id, v.persisted_type,
|
||||
v.long_value, dv.double_value, sv.string_value, serv.serializable_value
|
||||
from
|
||||
alf_audit_app app
|
||||
join alf_prop_value app_pv on (app_pv.id = app.app_name_id)
|
||||
join alf_prop_string_value app_sv on (app_sv.id = app_pv.long_value and app_pv.persisted_type = 3)
|
||||
join alf_audit_entry entry on (entry.audit_app_id = app.id)
|
||||
join alf_prop_value user_pv on (user_pv.id = entry.audit_user_id)
|
||||
join alf_prop_string_value user_sv on (user_sv.id = user_pv.long_value and user_pv.persisted_type = 3)
|
||||
|
||||
join alf_prop_link cl on (cl.root_prop_id = entry.audit_values_id)
|
||||
join alf_prop_value v on (cl.value_prop_id = v.id)
|
||||
left join alf_prop_double_value dv on (dv.id = v.long_value and v.persisted_type = 2)
|
||||
left join alf_prop_string_value sv on (sv.id = v.long_value and (v.persisted_type = 3 || v.persisted_type = 5))
|
||||
left join alf_prop_serializable_value serv on (serv.id = v.long_value and v.persisted_type = 4)
|
||||
<dynamic prepend="where">
|
||||
<isNotNull prepend="and" property="auditAppNameShort">
|
||||
app_sv.string_end_lower = #auditAppNameShort# and
|
||||
@@ -192,4 +145,67 @@
|
||||
entry.id
|
||||
</select>
|
||||
|
||||
<!-- Get audit entries -->
|
||||
<!-- TODO: Use compound parameters for string searching, possibly namespaced from propval -->
|
||||
<select id="select_AuditEntriesWithValues" parameterClass="AuditQueryParameters" resultMap="result_AuditQueryAllValues">
|
||||
select
|
||||
entry.id as audit_entry_id,
|
||||
user_sv.string_value as audit_user,
|
||||
app_sv.string_value as audit_app_name,
|
||||
entry.audit_time as audit_time,
|
||||
entry.audit_values_id as audit_values_id,
|
||||
|
||||
pl.root_prop_id, pl.current_prop_id, pl.value_prop_id, pl.key_prop_id,
|
||||
v.actual_type_id, v.persisted_type,
|
||||
v.long_value, dv.double_value, sv.string_value, serv.serializable_value
|
||||
from
|
||||
alf_audit_app app
|
||||
join alf_prop_value app_pv on (app_pv.id = app.app_name_id)
|
||||
join alf_prop_string_value app_sv on (app_sv.id = app_pv.long_value and app_pv.persisted_type = 3)
|
||||
join alf_audit_entry entry on (entry.audit_app_id = app.id)
|
||||
join alf_prop_value user_pv on (user_pv.id = entry.audit_user_id)
|
||||
join alf_prop_string_value user_sv on (user_sv.id = user_pv.long_value and user_pv.persisted_type = 3)
|
||||
|
||||
<isNotNull property="searchKey">
|
||||
join alf_prop_link sp_kpl on (sp_kpl.root_prop_id = entry.audit_values_id)
|
||||
join alf_prop_value sp_kv on (sp_kpl.key_prop_id = sp_kv.id)
|
||||
join alf_prop_string_value sp_ksv on (sp_ksv.id = sp_kv.long_value and sp_kv.persisted_type = 3)
|
||||
</isNotNull>
|
||||
<isNotNull property="searchValueString">
|
||||
join alf_prop_link sp_mpl on (sp_mpl.root_prop_id = entry.audit_values_id)
|
||||
join alf_prop_value sp_mv on (sp_mpl.value_prop_id = sp_mv.id)
|
||||
join alf_prop_string_value sp_msv on (sp_msv.id = sp_mv.long_value and sp_mv.persisted_type = 3)
|
||||
</isNotNull>
|
||||
|
||||
join alf_prop_link pl on (pl.root_prop_id = entry.audit_values_id)
|
||||
join alf_prop_value v on (pl.value_prop_id = v.id)
|
||||
left join alf_prop_double_value dv on (dv.id = v.long_value and v.persisted_type = 2)
|
||||
left join alf_prop_string_value sv on (sv.id = v.long_value and (v.persisted_type = 3 || v.persisted_type = 5))
|
||||
left join alf_prop_serializable_value serv on (serv.id = v.long_value and v.persisted_type = 4)
|
||||
<dynamic prepend="where">
|
||||
<isNotNull prepend="and" property="auditAppNameShort">
|
||||
app_sv.string_end_lower = #auditAppNameShort# and
|
||||
app_sv.string_crc = #auditAppNameCrc#
|
||||
</isNotNull>
|
||||
<isNotNull prepend="and" property="auditUserShort">
|
||||
user_sv.string_end_lower = #auditUserShort# and
|
||||
user_sv.string_crc = #auditUserCrc#
|
||||
</isNotNull>
|
||||
<isNotNull prepend="and" property="auditFromTime">
|
||||
<![CDATA[entry.audit_time >= #auditFromTime#]]>
|
||||
</isNotNull>
|
||||
<isNotNull prepend="and" property="auditToTime">
|
||||
<![CDATA[entry.audit_time < #auditToTime#]]>
|
||||
</isNotNull>
|
||||
<isNotNull prepend="and" property="searchKey">
|
||||
sp_ksv.string_value = #searchKey#
|
||||
</isNotNull>
|
||||
<isNotNull prepend="and" property="searchValueString">
|
||||
sp_msv.string_value = #searchValueString#
|
||||
</isNotNull>
|
||||
</dynamic>
|
||||
order by
|
||||
entry.id
|
||||
</select>
|
||||
|
||||
</sqlMap>
|
@@ -698,4 +698,18 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallout implementation from new audit DAO
|
||||
*
|
||||
* @throws UnsupportedOperationException always
|
||||
* @since 3.2
|
||||
*/
|
||||
public void findAuditEntries(
|
||||
AuditQueryCallback callback,
|
||||
String applicationName, String user, Long from, Long to, int maxResults,
|
||||
String searchKey, String searchString)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
@@ -346,10 +346,20 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO
|
||||
String applicationName, String user, Long from, Long to, int maxResults)
|
||||
{
|
||||
AuditQueryRowHandler rowHandler = new AuditQueryRowHandler(callback);
|
||||
findAuditEntries(rowHandler, applicationName, user, from, to, maxResults);
|
||||
findAuditEntries(rowHandler, applicationName, user, from, to, maxResults, null, null);
|
||||
}
|
||||
|
||||
public void findAuditEntries(
|
||||
AuditQueryCallback callback,
|
||||
String applicationName, String user, Long from, Long to, int maxResults,
|
||||
String searchKey, String searchString)
|
||||
{
|
||||
AuditQueryRowHandler rowHandler = new AuditQueryRowHandler(callback);
|
||||
findAuditEntries(rowHandler, applicationName, user, from, to, maxResults, searchKey, searchString);
|
||||
}
|
||||
|
||||
protected abstract void findAuditEntries(
|
||||
AuditQueryRowHandler rowHandler,
|
||||
String applicationName, String user, Long from, Long to, int maxResults);
|
||||
String applicationName, String user, Long from, Long to, int maxResults,
|
||||
String searchKey, String searchString);
|
||||
}
|
||||
|
@@ -98,4 +98,9 @@ public interface AuditDAO
|
||||
void findAuditEntries(
|
||||
AuditQueryCallback callback,
|
||||
String applicationName, String user, Long from, Long to, int maxResults);
|
||||
|
||||
void findAuditEntries(
|
||||
AuditQueryCallback callback,
|
||||
String applicationName, String user, Long from, Long to, int maxResults,
|
||||
String searchKey, String searchString);
|
||||
}
|
@@ -37,6 +37,7 @@ import org.alfresco.repo.domain.contentdata.ContentDataDAO;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
@@ -124,6 +125,13 @@ public class AuditDAOTest extends TestCase
|
||||
}
|
||||
|
||||
public void testAuditEntry() throws Exception
|
||||
{
|
||||
doAuditEntryImpl(1000);
|
||||
}
|
||||
/**
|
||||
* @return Returns the name of the application
|
||||
*/
|
||||
private String doAuditEntryImpl(final int count) throws Exception
|
||||
{
|
||||
final File file = AbstractContentTransformerTest.loadQuickTestFile("pdf");
|
||||
assertNotNull(file);
|
||||
@@ -140,7 +148,6 @@ public class AuditDAOTest extends TestCase
|
||||
};
|
||||
final Long sessionId = txnHelper.doInTransaction(createAppCallback);
|
||||
|
||||
final int count = 1000;
|
||||
final String username = "alexi";
|
||||
RetryingTransactionCallback<Void> createEntryCallback = new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
@@ -161,5 +168,38 @@ public class AuditDAOTest extends TestCase
|
||||
System.out.println(
|
||||
"Time for " + count + " entry creations was " +
|
||||
((double)(after - before)/(10E6)) + "ms");
|
||||
// Done
|
||||
return appName;
|
||||
}
|
||||
|
||||
public void testAuditQuery() throws Exception
|
||||
{
|
||||
// Some entries
|
||||
doAuditEntryImpl(1);
|
||||
|
||||
// Find everything, bug look for a specific key
|
||||
final AuditQueryCallback callback = new AuditQueryCallback()
|
||||
{
|
||||
public boolean handleAuditEntry(
|
||||
Long entryId,
|
||||
String applicationName,
|
||||
String user,
|
||||
long time,
|
||||
Map<String, Serializable> values)
|
||||
{
|
||||
System.out.println(values);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
RetryingTransactionCallback<Void> findCallback = new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
auditDAO.findAuditEntries(callback, null, null, null, null, -1, "/a/b/c", null);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
txnHelper.doInTransaction(findCallback);
|
||||
}
|
||||
}
|
||||
|
@@ -41,6 +41,8 @@ public class AuditQueryParameters
|
||||
private Pair<String, Long> auditUserCrcPair;
|
||||
private Long auditFromTime;
|
||||
private Long auditToTime;
|
||||
private String searchKey;
|
||||
private String searchValueString;
|
||||
|
||||
public AuditQueryParameters()
|
||||
{
|
||||
@@ -56,6 +58,8 @@ public class AuditQueryParameters
|
||||
.append(", auditUserCrcPair=").append(auditUserCrcPair)
|
||||
.append(", auditFromTime").append(new Date(auditFromTime))
|
||||
.append(", auditToTime").append(new Date(auditToTime))
|
||||
.append(", searchKey").append(searchKey)
|
||||
.append(", searchValueString").append(searchValueString)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
@@ -119,4 +123,24 @@ public class AuditQueryParameters
|
||||
{
|
||||
this.auditToTime = to;
|
||||
}
|
||||
|
||||
public String getSearchKey()
|
||||
{
|
||||
return searchKey;
|
||||
}
|
||||
|
||||
public void setSearchKey(String searchKey)
|
||||
{
|
||||
this.searchKey = searchKey;
|
||||
}
|
||||
|
||||
public String getSearchValueString()
|
||||
{
|
||||
return searchValueString;
|
||||
}
|
||||
|
||||
public void setSearchValueString(String searchValueString)
|
||||
{
|
||||
this.searchValueString = searchValueString;
|
||||
}
|
||||
}
|
||||
|
@@ -155,11 +155,8 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl
|
||||
@Override
|
||||
protected void findAuditEntries(
|
||||
final AuditQueryRowHandler rowHandler,
|
||||
String appName,
|
||||
String user,
|
||||
Long from,
|
||||
Long to,
|
||||
int maxResults)
|
||||
String appName, String user, Long from, Long to, int maxResults,
|
||||
String searchKey, String searchString)
|
||||
{
|
||||
AuditQueryParameters params = new AuditQueryParameters();
|
||||
if (appName != null)
|
||||
@@ -175,6 +172,8 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl
|
||||
}
|
||||
params.setAuditFromTime(from);
|
||||
params.setAuditToTime(to);
|
||||
params.setSearchKey(searchKey);
|
||||
params.setSearchValueString(searchString);
|
||||
|
||||
// RowHandlers in RowHandlers: See 'groupBy' issue https://issues.apache.org/jira/browse/IBATIS-503
|
||||
RowHandler shreddedRowHandler = new RowHandler()
|
||||
|
Reference in New Issue
Block a user