Hi All,
Can we add a timestamp on the primary attachment been downloaded.
How can we achieve it?
Any references would be appreciated
Hi @DKWc
The information is stored as a Security Audit log
if it is not activated you can activate the logging of the download event.
cs269060 - WCAudit tablespace (e.g. table DOWNLOADEVENTINFO, AUDITRECORD)
wt.content.ContentServiceEvent/READ_CONTENT is the audit log type
Then you can create a DataUtility for an attribute that retrieve last audit log record with download event.
There is one issue with Visualization. Visualization worker also download the primary content.
Hi @DKWc
here is an example - I used attribute AV_CODE but it does not mater
here is a configuration and a place where you set the datautility
service.properties
and finally here s a code for DataUtility
package cz.aveng.HELTest1;
import com.ptc.core.components.descriptor.ModelContext;
import com.ptc.core.components.factory.dataUtilities.DefaultDataUtility;
import com.ptc.core.components.rendering.guicomponents.Label;
import wt.audit.AuditRecord;
import wt.doc.WTDocument;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.pds.StatementSpec;
import wt.query.*;
import wt.util.WTException;
/**
* Datautilita for timestamp display from AuditRecord of Download event
* <Service context="default" name="com.ptc.core.components.descriptor.DataUtility"
* targetFile="codebase/service.properties">
* <Option cardinality="duplicate" order="1" overridable="true"
* requestor="java.lang.Object"
* selector="downloadAuditEventTimeStamp"
* serviceClass="cz.aveng.HELTest1.AVCustomTestDataUtility"/>
* </Service>
*/
public class AVCustomTestDataUtility extends DefaultDataUtility
{
public AVCustomTestDataUtility()
{
}
public Object getDataValue(String var1, Object peristable, ModelContext var3) throws WTException
{
Object retValue = super.getDataValue(var1, peristable, var3);
Label label = new Label(var1);
if (peristable instanceof WTDocument)
{
WTDocument doc = (WTDocument) peristable;
try
{
String searchCondition = "*/wt.content.ContentServiceEvent/READ_CONTENT";
QuerySpec queryspec = new QuerySpec();
int idLinkObject = queryspec.appendClassList(AuditRecord.class, true);
CompositeWhereExpression andCondition = new CompositeWhereExpression(LogicalOperator.AND);
andCondition.append(new SearchCondition(AuditRecord.class, AuditRecord.EVENT_KEY, SearchCondition.LIKE, searchCondition, false), new int[]{idLinkObject});
andCondition.append(new SearchCondition(AuditRecord.class, AuditRecord.TARGET_NUMBER, SearchCondition.LIKE, doc.getNumber(), false), new int[]{idLinkObject});
queryspec.appendWhere(andCondition, new int[]{idLinkObject, idLinkObject});
queryspec.appendOrderBy(new OrderBy(new ClassAttribute(AuditRecord.class, AuditRecord.CREATE_TIMESTAMP), true), new int[]{0});
QueryResult queryResult = PersistenceHelper.manager.find((StatementSpec) queryspec);
while (queryResult.hasMoreElements())
{
Object resultObj = queryResult.nextElement();
if (resultObj instanceof Persistable[])
{
Object resultAuditObj = ((Persistable[])resultObj)[0];
if (resultAuditObj instanceof AuditRecord)
{
retValue = ((AuditRecord) resultAuditObj).getCreateTimestamp();
break;
}
}
}
} catch (WTException e)
{
e.printStackTrace();
}
}
return retValue;
}
}
last thing, I would recommend to create database indexes on two columns for the AuditRecord table.
targetNumber
it will increase performance
PetrH