刘 鸿 王 枫
1(中国科学院等离子体物理研究所 安徽 合肥 230031) 2(中国科学技术大学 安徽 合肥 230022)
EAST Document Management(EDM)是一个兼具丰富文档管理功能、强大用户管理与权限控制功能和多版本工作流控制功能的集成在线文档管理系统[1],用来集中管理国家大科学工程项目全超导托卡马克实验装置EAST[2]相关的文档。目前已有的EDM文档管理系统是基于Web端的开发,对文档的操作需要借助PC端。这不利于实验人员及时地获取与实验相关的文档信息。而随着移动设备的不断普及,人们上网的习惯也逐渐由PC端向移动端转变,所以需要开发一套基于移动平台的EAST文档管理系统,在原有的系统基础上进行有效的补充、扩展和延伸,保证通信安全和文档存储安全的前提下方便科研人员在移动设备上对文档进行增删改查[3]。
Android平台是Google旗下的一款开源的手机操作系统,开源的特点使得国内厂商可以对操作系统进行定制生产。相对于Apple公司的Iphone手机,Android手机可以防止系统本身对信息的泄漏。经调研EAST科研人员87.4%使用的是Android操作系统手机,因此设计开发基于Android平台的EAST文档管理系统是可取的。
Android平台EAST文档管理系统总体框架分为三个部分[4],如图1所示。中间部分是服务器,两边分别是客户端和数据库。客户端通过PHP访问接口和服务器相连,服务器通过数据库接口和数据库相连,客户端和数据库不能直接通信。这样的架构设计,既可以保证数据库的安全,将客户端和数据库隔离,又可以方便客户端的调用。让客户端只关心数据内容,而不用关心怎么从数据库中获取数据。
图1 系统总体框架
如图2所示,客户端中设计一个自定义的栈结构,可以在同一个Activity容器中进行无限层级文件夹目录操作,如文件夹的进入、退出、任意层级跳转等。同时在客户端中封装了可扩展的文档元数据父类。继承该类的不同文档子类可以在同一目录中同时显示,不需要多次请求数据来展示,从而提高了用户体验。
图2 客户端框架
服务器是系统设计的重要组成部分,它决定了用客户端什么方式请求数据,用什么格式解析数据,系统的服务器使用通用的LAMP架构[5],并使用Apache提供接口的访问操作,使用PHP提供对数据库的增删改查。如图3所示。
图3 服务器框架
移动客户端的验证功能大部分都是基于短信平台,目前市场是有众多的短信验证平台,如阿里云短信验证平台等。这些平台的优势是封装了功能代码,开发者可以直接使用,缺点是客户端的验证功能需要依赖于平台的存在而存在,如果平台停止服务,系统验证功能将会失效。这与本系统轻量级低耦合高安全性的目标不相符,因此我们需要设计基于短信猫硬件开发自己的短信验证功能[6]。
短信猫是一个提供短信发送功能的装置,配置完成后,可以向SQL server数据库的outbox表中写入目标电话,发送内容,短信猫会自动将内容发送出去。基于此特点,设计短信验证接口。
接口内部实现如下:
1) 提供post请求,并接收3个参数:
“telephone_number”=”value1”
“user_name”=”value2”
“secret_key”=”value3”
其中:telephone_number表示目标电话,user_name表示调用者是谁,secret_key表示平台和服务器约定的密钥。
2) 自动生成一个6位数的验证码作为发送内容。
3) 访问SQL server数据库,向outbox表中写入目标电话,短信内容。
4) 短信猫监控程序自动发送内容到目标手机。
5) 结果以json格式返回给客户端:
[{ ″result_code ″: ″value1″,
″ result ″: ″value2″}]
result_code值为-1,-2,-3等。其中:
-3:sqlserver数据库操作失败
-2:telephone为空
-1:telephone不为空但格式不正确
1:短信发送正常
在result_code为1时候,result值才是有效的。此时可以对比result值与用户输入的验证码,如果一致则验证通过。
目录显示是本系统的特点之一,Android平台没有自带的控件可以实现无限层级的目录显示,需要根据系统的特点设计一个合理的数据结构。考虑到目录操作的特点,如点击进入、返回退出、向前任意层级跳转,这样的操作类似于栈的先进后出的特点,基于此特点设计了基于堆栈式文档[7]并列显示功能。如图4从左到右分别是L-test目录的进栈操作,L-test目录的出栈操作,以及直接跳转到User-L目录的出栈操作。其中任意层级的跳转,需要把该层级上面的内容全部移除,这与栈的操作也非常吻合。自定的目录栈操作既保证了系统的封闭特点,又解决了无限层级的目录访问问题。
图4 自定义目录栈操作
public class ProfileStack {
boolean isEmpty();
//栈是否为空
void clear();
//清空栈
int length();
//栈的长度
boolean push(Profile p);
//文档集合进栈
Profile pop();
//弹出栈顶文档集合
Profile peek()
//查看栈顶文档集合但不移除
}
其中Profile类封装了Path类和File类,这使得目录栈结构并不是简单的一维Path路径类结构,而是同时包含多格式多类型的File文档类的二维结构。
从数据库获取到的数据是一种多格式多类型元数据,对于这样数据的解析。存储和展示是本系统的另外一个难点,即目录和文档的并列显示问题。
通常情况下,每个层级不仅仅只有目录文件夹,还可能会有具体的文档存在,如pdf文档。这种并列存在的形式,对目录栈结构的设计有了更高的要求,如果从简单的角度考虑,目录文件夹和具体的文档可以看成统一的文件形式共同存储在数据库的同一张表中。但是EAST文档管理系统是对一个大科学工程的海量文档进行管理,所有的数据元的设计都是合理和严谨的,所以在数据库中目录文件夹和具体的文档是存在不同的表中,并没有放在同一张表中,这也体现系统设计的完整性和难度所在。
数据库中目录文件夹和具体文档是不同类别的存储,在客户端中需要设计一个从解析、存储到展示为一体的方法来解决这个问题。并且,随着EAST每年实验的不断推进,未来会有更多种类的数据元存储在系统中,预留合适的接口方便后面扩展也十分重要。
在目录和文档并列显示的要求下,客户端的开发中,本文实现了一整套的文件继承关系。基于此继承关系的文件,可以无视客户端接收数据的不同,将原本存储在不同的表中的数据,进行分类解析,同类保存,然后再分类显示。这种由分类,到同类再到分类的过程,是父类对象和子类对象相互转化的过程,体现了面向对象语言的友好之处,可以更加灵活地对不同数据进行操作。文档类的整体架构和继承关系如图5所示。
图5 文档UML类图
基于这样的类结构,可以在不知道哪种类型文档的情况下,使用父类File表示所有的文档。在具体要显示文档信息的时候,通过父类的type变量判断文档的具体类型,并强制转换成对应的文档类型,获取子对象的各种变量值进行展示即可。未来即使有更多的文档元数据添加进来,如vedio格式的元数据,只要这些类统一继承自File类,依然可以使用相同的方法就行文档类别的判断、转化、展示。
文档的工作流是EAST文档管理系统的重要组成部分。一般的文档管理系统的文档都是静态的,或者是单工作流。EAST的文档是多区域科研人员协同工作的成果,所以文档的工作流是非静态,多线路的工作流。图6是文档工作流的具体流程。
图6 文档工作流图
由图6可知,同一个文档有一个作者,但是可以有一个或多个合作者,所有的作者和合作者可以并行地对文档进行签署,所有的签署完成以后才会进入审批状态,审批人可以设置通过,也可以拒绝通过。在整个工作流中,还可以有多个评阅人对文档进行审阅评论,评阅人只能评论不能更改流程状态。基于以上特点,很容易开发出基于多通道的文档工作流。
文档的版本控制与工作流结合起来,变成了一个复杂的多通道并行推进的流程。版本工作流状态将影响版本更迭过程,current版本必须是所有没有过时(非obsolete)版本中最成熟的版本,即工作流状态级别最高的版本。带工作流的版本迭代规则[8]如图7所示。
图7 文档版本控制图
由图7可知,带工作流的版本控制主要分成三个部分。
1) 新建的文档默认是最新的文档,也就是current版本。
2) 如果更新文档,将更新文档的工作流和该文档在数据库中最成熟工作流进行比较,如果大于,说明更新的文档是最让人满意的文档,用更新的文档替换现在的文档,并让current指向更新的文档,其他文档都设置为obsolete;如果小于,说明原来的文档最让人满意,那么current指向不变。
3) 如果数据库中非obsolete文档的状态变化,变化的文档就相当于2)中更新的文档,那么回到2)中比较状态流成熟度的判定条件来决定current指向哪个文档。
1) 文档扩展名检测。为了保护服务器的安全,防止恶意程序如exe等非法文件上传,系统对上传的文档类型有严格的要求。同时为了避免将exe文件改变拓展名如demo.exe改成demo.txt而被上传到服务器,系统会在文档上传前用非文档名的方法判断扩展名具体实现方式是通过文档路径名获取File实例,并使用getName()方法获取真实的文档名称。获取到文件名后,用String的endsWith(″.*″)方法判断是否是指定的文件。其中*可以是doc、pdf等扩展名,如果文档扩展名是系统限定类型之内的,将会通过检测。
2) 文档内容检测。文档上传前还需要对内容进行检测,是否包含敏感词汇,是否包含操作数据库特定表的SQL语句。借助于jxl.jar、tm-extractors-0.4.jar等jar包可以对xls、doc等文档进行解析,并与系统设置的敏感词汇,敏感SQL语句模糊匹配,如果没有查找到,则通过检测。
3) 文档上传。对于已经通过检测的文档,可以使用基于OKHttp框架的post方式进行文档上传。客户端中的post上传其实就是模拟了表单提交,只要把发送的文件信息拼接到头里面,但是这里的头信息一定要按照规范格式去写,OKHttp中的addFormDataPart(String name, String filename, RequestBody body)方法,已经实现了具体格式的封装,按要求传入即可完成上传操作。
文档的下载过程中,服务器端通过下载函数接口隐藏文档在服务器的真实路径,下载的路径设置为url+下载函数+文档标识符eid+文档版本号。例如需要下载文档的eid为AAAA,版本号为2.0的文档的下载路径为https://edm.ipp.ac.cn/file_download/AAAA/2.0。该方法规避了客户端必须获取文档真实路径的来下载文档的风险。
考虑到EAST文档下载后的安全性,不能将普通数据与EAST数据混合存储,在开发中主要用到Android中的context.getExternalFileDir(String type)方法,将文档存储在客户端包名下的files文档目录下。这个目录理论上别的应用是无法访问的,也就不会导致信息泄。但是Android系统很多都被root过,获得root权限的恶意应用仍然有可能获取文档的内容,所在下载之后,对文档进行了MD5加密措施,双重保护文档。
当需要查看文档的时候,开启辅助线程,将文档复制到sdcard公用目录中,然后进行解密操作,最后使用intent.setDataAndType(Uri.fromFile(new File(filename)), "application/*")方法来打开对应文档。当客户端退出时候,会强制删除sdcard公用目录中的文档。
系统的登录、多语言的支持、快捷方式的创建、文档的查询删除、文档的评论等功能,都是基于OKhttp开源框架与服务器的可靠通信。如果数据在无加密的传输通道或以明文方式进行传输,使得数据容易被监听或篡改[9]。为了保证通信的可靠性,服务器由http升级为https,同时还在参数中使用约定的加密参数[10],确保访问者是已知用户。客户端获取到服务器的json格式数据,对数据解析,并显示在客户端中,类似的方法,可以实现客户端的其他基本功能。
EAST文档数据的安全性是系统设计过程中的重要部分,因此对PHP接口和本地文档进行了单独测试。对于本地下载的文档,使用了已经root和没有root两部手机测试。结果表明,虽然已经root的手机可以访问本地文档,但是因为经过加密操作,打开的文档为乱码。没有root的手机,无法访问到本地文档,系统在一定程度上保证了安全性。
为了保证科研人员高并发使用Android平台的EAST文档管理系统,需要进行压力测试。在某个客户端中开启1 000个线程访问服务器,同时使用部分真机和虚拟机一起访问服务器,测试结果表现良好,真机访问并没有因为其他设备访问而受到影响。
性能测试工具采用了网易公司的Emmagee工具。它是网易公司开发的一个Android性能检测工具,主要检测APP的CPU占用率,内存占用率和流量使用情况,同时开发者可以自定义配置监控的频率并显示结果,最终生成一份性能统计文件[11]。
本文使用的是Emmagee2.5.1版本软件,对基于Android平台的EAST文档管理系统就行性能检测。Emmagee工具生成的是csv格式文本,可以先导入到Excel中,再生成相应的图表。Emmagee检测报告单如图8所示,基于检测报告单的CPU使用率,如图9所示。
图9 CPU使用率
由图8可知,客户端的流量损失量低,当没有文档的上传下载时候基本不耗流量。由图9可知,客户端在使用阶段,CPU占有率处于合理位置,不需要消耗过多的系统资源,系统可靠性强,流量稳定,电量消耗少,总体来看系统可以满足科研人员的正常使用。
为了满足与EAST相关的科研人员快速准确地获取文档信息,本文设计开发了基于Android平台的EAST文档管理系统,并保证通信安全,文档存储安全的前提下,对EAST文档进行工作流控制、版本控制、以及文档上传、下载、查询、删除等基本操作。系统整体设计高效安全兼容性好,文档类的继承关系使得文档类型的可扩展性强。基于Android平台的EAST文档管理系统已经在实验中使用,并收到了良好的预期效果。