查询Auditing history及应用说明

        在《FileNet Auditing简单配置及说明》中已经介绍了Auditing的作用及其能够统计的相关内容。可以说其对评估一个文档类产品的利用情况很有价值,对此早些购买FileNet产品的公司(如zhy)会直接在XT上进行定制开发,使其具备文档报表统计功能。

         整个报表统计过程,其实就是对auditing history的查询过程,其映射的是对event log的查询。就像我们查询Document类型(或自定义Document类型)一样,我们使用的方式是相同的。在理解好Query语法的基础上,便能容易的进行相关操作了。代码示例如下所示。

public long getAuditingInfos(ObjectStore os,
												Date startDate,
												Date endDate,
												Id auditingType,
												Boolean 				needParentClassType,
												String topParentClass,
												
) throws Exception{
		
		
		long total = 0;
		
		AuditingInfoBean bean = null;
		RepositoryRowSet rrs = null;
		RepositoryRow rr = null;
		
		if(startDate != null && endDate != null && 
				(rrs = buildData(os,startDate,endDate,auditingType)) != null){
			
			PageIterator iter = rrs.pageIterator();
			while (iter.nextPage())
			{
			    Object[] currentPage = iter.getCurrentPage();
			    if(currentPage != null){
			    	for(int i=0;i<currentPage.length;i++){
			    		rr = (RepositoryRow)currentPage[i];
			    		
			    		if(null != rr && rr.getProperties().getInteger32Value(PropertyNames.EVENT_STATUS) == 0){
			    			
					    	try{
					    		rr.getProperties().getIdValue(PropertyNames.ID).toString();
					    		rr.getProperties().getObjectValue(PropertyNames.CREATOR);
					    		rr.getProperties().getIdValue(PropertyNames.SOURCE_OBJECT_ID);
					    		Id classId = rr.getProperties().getIdValue(PropertyNames.SOURCE_CLASS_ID);
					    		PropertyFilter filter = new PropertyFilter();
								FilterElement ele0 = new FilterElement(null, null, null, PropertyNames.SYMBOLIC_NAME, null);
								FilterElement ele1 = new FilterElement(null, null, null, PropertyNames.SUPERCLASS_DESCRIPTION, null);
								filter.addIncludeProperty(ele0);
								filter.addIncludeProperty(ele1);
								ClassDescription classDescription = Factory.ClassDescription.fetchInstance(os, classId, filter);
								String selfSymbolicName = classDescription.get_SymbolicName();
					    		
					    	}catch(Exception e){
					    		logger.error(e.toString());
					    		continue;
					    	}
			    		}
			    	}
			    }
			}
		}
		
		return total;
	}
	
	private RepositoryRowSet buildData(ObjectStore os,Date startDate,Date endDate,Id auditingType){

		RepositoryRowSet rrs  = null;
		
		if(AuditingUtil.CREATIONEVENT == auditingType 
				|| AuditingUtil.GETCONTENTEVENT == auditingType){
			
			String sqlString = "SELECT "  + PropertyNames.CREATOR + "," + 
											PropertyNames.ID + "," + 
											PropertyNames.DATE_CREATED + "," + 
											PropertyNames.EVENT_STATUS + "," + 
											PropertyNames.SOURCE_CLASS_ID + "," + 
											PropertyNames.SOURCE_OBJECT_ID;

			SearchSQL searchSql = new SearchSQL(sqlString + 
									" FROM " + auditingType + 
							        " WHERE " + 
							        	PropertyNames.DATE_CREATED + " >= " + dateFormat(startDate) + 
							        	" AND " + 
							        	PropertyNames.DATE_CREATED  + " < " + dateFormat(endDate) +
							        " ORDER BY " + PropertyNames.DATE_CREATED);
			
			SearchScope ss = new SearchScope(os);
			
			PropertyFilter filter = new PropertyFilter();
			FilterElement ele1 = new FilterElement(null, null, null, PropertyNames.EVENT_STATUS, null);
			FilterElement ele2 = new FilterElement(null, null, null, PropertyNames.CREATOR, null);
			FilterElement ele3 = new FilterElement(null, null, null, PropertyNames.DATE_CREATED, null);
			FilterElement ele4 = new FilterElement(null, null, null, PropertyNames.SOURCE_CLASS_ID, null);
			FilterElement ele5 = new FilterElement(null, null, null, PropertyNames.SOURCE_OBJECT_ID, null);
			filter.addIncludeProperty(ele1);
			filter.addIncludeProperty(ele2);
			filter.addIncludeProperty(ele3);
			filter.addIncludeProperty(ele4);
			filter.addIncludeProperty(ele5);
			
			rrs = ss.fetchRows(searchSql, 1000, filter, true);
		}

		return rrs;
	}
	
	private String dateFormat(Date date){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String dateStr = sdf.format(date);
		sdf = new SimpleDateFormat("HHmmss");
		dateStr = dateStr + "T" + sdf.format(date) + "Z";
		return dateStr;
	}

         FileNet提供了对流程的报表分析工具(process Analyzer),却没有提供与Auditing相互配合的产品。这种直接定制性开发的工作虽然功能上可以实现,但效率问题是已经在XT上定制出来的功能随着zhy某分公司几十万附件的量也使得这个功能形同虚设。究其原因不是FileNet存储不够优化,而是auditing存储的是相应操作事件相关的内容,虽然也已存储着操作的文档实例,但要借此获取到文档相关信息(如名称、甚至是操作者所在部门)则会非常耗时。

         针对此类问题可以考虑去直接理清FileNet数据库继而直接操作数据库,但这种风险较高,而且产品升级也可能有所不便;另外可以考虑将业务相关数据在定时任务中转移到应用的业务库中,这种短时间的auditing查询,且是在应用空闲时间进行的,会较易接受,虽然这种方式会有一定延迟,但统计本身的时间量很大,这种一天甚至更短时间的延迟是可以接受的;当然,我们还可以完全不使用auditing,直接在业务中记录相关要统计的数据,但这样做除了要做更多的开发工作,更要紧的是对已经成型的产品(或应用)的改动会很大,可能会带来比这种开发更大的工作量(如测试)。所以,可以根据是项目阶段在后两种中选择,如果是FileNet内部人员可能会更喜欢第一种,但要考虑升级风险。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值