劉 鴻 王 楓
1(中國科學院等離子體物理研究所 安徽 合肥 230031) 2(中國科學技術(shù)大學 安徽 合肥 230022)
EAST Document Management(EDM)是一個兼具豐富文檔管理功能、強大用戶管理與權(quán)限控制功能和多版本工作流控制功能的集成在線文檔管理系統(tǒng)[1],用來集中管理國家大科學工程項目全超導托卡馬克實驗裝置EAST[2]相關(guān)的文檔。目前已有的EDM文檔管理系統(tǒng)是基于Web端的開發(fā),對文檔的操作需要借助PC端。這不利于實驗人員及時地獲取與實驗相關(guān)的文檔信息。而隨著移動設(shè)備的不斷普及,人們上網(wǎng)的習慣也逐漸由PC端向移動端轉(zhuǎn)變,所以需要開發(fā)一套基于移動平臺的EAST文檔管理系統(tǒng),在原有的系統(tǒng)基礎(chǔ)上進行有效的補充、擴展和延伸,保證通信安全和文檔存儲安全的前提下方便科研人員在移動設(shè)備上對文檔進行增刪改查[3]。
Android平臺是Google旗下的一款開源的手機操作系統(tǒng),開源的特點使得國內(nèi)廠商可以對操作系統(tǒng)進行定制生產(chǎn)。相對于Apple公司的Iphone手機,Android手機可以防止系統(tǒng)本身對信息的泄漏。經(jīng)調(diào)研EAST科研人員87.4%使用的是Android操作系統(tǒng)手機,因此設(shè)計開發(fā)基于Android平臺的EAST文檔管理系統(tǒng)是可取的。
Android平臺EAST文檔管理系統(tǒng)總體框架分為三個部分[4],如圖1所示。中間部分是服務(wù)器,兩邊分別是客戶端和數(shù)據(jù)庫??蛻舳送ㄟ^PHP訪問接口和服務(wù)器相連,服務(wù)器通過數(shù)據(jù)庫接口和數(shù)據(jù)庫相連,客戶端和數(shù)據(jù)庫不能直接通信。這樣的架構(gòu)設(shè)計,既可以保證數(shù)據(jù)庫的安全,將客戶端和數(shù)據(jù)庫隔離,又可以方便客戶端的調(diào)用。讓客戶端只關(guān)心數(shù)據(jù)內(nèi)容,而不用關(guān)心怎么從數(shù)據(jù)庫中獲取數(shù)據(jù)。
圖1 系統(tǒng)總體框架
如圖2所示,客戶端中設(shè)計一個自定義的棧結(jié)構(gòu),可以在同一個Activity容器中進行無限層級文件夾目錄操作,如文件夾的進入、退出、任意層級跳轉(zhuǎn)等。同時在客戶端中封裝了可擴展的文檔元數(shù)據(jù)父類。繼承該類的不同文檔子類可以在同一目錄中同時顯示,不需要多次請求數(shù)據(jù)來展示,從而提高了用戶體驗。
圖2 客戶端框架
服務(wù)器是系統(tǒng)設(shè)計的重要組成部分,它決定了用客戶端什么方式請求數(shù)據(jù),用什么格式解析數(shù)據(jù),系統(tǒng)的服務(wù)器使用通用的LAMP架構(gòu)[5],并使用Apache提供接口的訪問操作,使用PHP提供對數(shù)據(jù)庫的增刪改查。如圖3所示。
圖3 服務(wù)器框架
移動客戶端的驗證功能大部分都是基于短信平臺,目前市場是有眾多的短信驗證平臺,如阿里云短信驗證平臺等。這些平臺的優(yōu)勢是封裝了功能代碼,開發(fā)者可以直接使用,缺點是客戶端的驗證功能需要依賴于平臺的存在而存在,如果平臺停止服務(wù),系統(tǒng)驗證功能將會失效。這與本系統(tǒng)輕量級低耦合高安全性的目標不相符,因此我們需要設(shè)計基于短信貓硬件開發(fā)自己的短信驗證功能[6]。
短信貓是一個提供短信發(fā)送功能的裝置,配置完成后,可以向SQL server數(shù)據(jù)庫的outbox表中寫入目標電話,發(fā)送內(nèi)容,短信貓會自動將內(nèi)容發(fā)送出去?;诖颂攸c,設(shè)計短信驗證接口。
接口內(nèi)部實現(xiàn)如下:
1) 提供post請求,并接收3個參數(shù):
“telephone_number”=”value1”
“user_name”=”value2”
“secret_key”=”value3”
其中:telephone_number表示目標電話,user_name表示調(diào)用者是誰,secret_key表示平臺和服務(wù)器約定的密鑰。
2) 自動生成一個6位數(shù)的驗證碼作為發(fā)送內(nèi)容。
3) 訪問SQL server數(shù)據(jù)庫,向outbox表中寫入目標電話,短信內(nèi)容。
4) 短信貓監(jiān)控程序自動發(fā)送內(nèi)容到目標手機。
5) 結(jié)果以json格式返回給客戶端:
[{ ″result_code ″: ″value1″,
″ result ″: ″value2″}]
result_code值為-1,-2,-3等。其中:
-3:sqlserver數(shù)據(jù)庫操作失敗
-2:telephone為空
-1:telephone不為空但格式不正確
1:短信發(fā)送正常
在result_code為1時候,result值才是有效的。此時可以對比result值與用戶輸入的驗證碼,如果一致則驗證通過。
目錄顯示是本系統(tǒng)的特點之一,Android平臺沒有自帶的控件可以實現(xiàn)無限層級的目錄顯示,需要根據(jù)系統(tǒng)的特點設(shè)計一個合理的數(shù)據(jù)結(jié)構(gòu)??紤]到目錄操作的特點,如點擊進入、返回退出、向前任意層級跳轉(zhuǎn),這樣的操作類似于棧的先進后出的特點,基于此特點設(shè)計了基于堆棧式文檔[7]并列顯示功能。如圖4從左到右分別是L-test目錄的進棧操作,L-test目錄的出棧操作,以及直接跳轉(zhuǎn)到User-L目錄的出棧操作。其中任意層級的跳轉(zhuǎn),需要把該層級上面的內(nèi)容全部移除,這與棧的操作也非常吻合。自定的目錄棧操作既保證了系統(tǒng)的封閉特點,又解決了無限層級的目錄訪問問題。
圖4 自定義目錄棧操作
public class ProfileStack {
boolean isEmpty();
//棧是否為空
void clear();
//清空棧
int length();
//棧的長度
boolean push(Profile p);
//文檔集合進棧
Profile pop();
//彈出棧頂文檔集合
Profile peek()
//查看棧頂文檔集合但不移除
}
其中Profile類封裝了Path類和File類,這使得目錄棧結(jié)構(gòu)并不是簡單的一維Path路徑類結(jié)構(gòu),而是同時包含多格式多類型的File文檔類的二維結(jié)構(gòu)。
從數(shù)據(jù)庫獲取到的數(shù)據(jù)是一種多格式多類型元數(shù)據(jù),對于這樣數(shù)據(jù)的解析。存儲和展示是本系統(tǒng)的另外一個難點,即目錄和文檔的并列顯示問題。
通常情況下,每個層級不僅僅只有目錄文件夾,還可能會有具體的文檔存在,如pdf文檔。這種并列存在的形式,對目錄棧結(jié)構(gòu)的設(shè)計有了更高的要求,如果從簡單的角度考慮,目錄文件夾和具體的文檔可以看成統(tǒng)一的文件形式共同存儲在數(shù)據(jù)庫的同一張表中。但是EAST文檔管理系統(tǒng)是對一個大科學工程的海量文檔進行管理,所有的數(shù)據(jù)元的設(shè)計都是合理和嚴謹?shù)?,所以在?shù)據(jù)庫中目錄文件夾和具體的文檔是存在不同的表中,并沒有放在同一張表中,這也體現(xiàn)系統(tǒng)設(shè)計的完整性和難度所在。
數(shù)據(jù)庫中目錄文件夾和具體文檔是不同類別的存儲,在客戶端中需要設(shè)計一個從解析、存儲到展示為一體的方法來解決這個問題。并且,隨著EAST每年實驗的不斷推進,未來會有更多種類的數(shù)據(jù)元存儲在系統(tǒng)中,預(yù)留合適的接口方便后面擴展也十分重要。
在目錄和文檔并列顯示的要求下,客戶端的開發(fā)中,本文實現(xiàn)了一整套的文件繼承關(guān)系?;诖死^承關(guān)系的文件,可以無視客戶端接收數(shù)據(jù)的不同,將原本存儲在不同的表中的數(shù)據(jù),進行分類解析,同類保存,然后再分類顯示。這種由分類,到同類再到分類的過程,是父類對象和子類對象相互轉(zhuǎn)化的過程,體現(xiàn)了面向?qū)ο笳Z言的友好之處,可以更加靈活地對不同數(shù)據(jù)進行操作。文檔類的整體架構(gòu)和繼承關(guān)系如圖5所示。
圖5 文檔UML類圖
基于這樣的類結(jié)構(gòu),可以在不知道哪種類型文檔的情況下,使用父類File表示所有的文檔。在具體要顯示文檔信息的時候,通過父類的type變量判斷文檔的具體類型,并強制轉(zhuǎn)換成對應(yīng)的文檔類型,獲取子對象的各種變量值進行展示即可。未來即使有更多的文檔元數(shù)據(jù)添加進來,如vedio格式的元數(shù)據(jù),只要這些類統(tǒng)一繼承自File類,依然可以使用相同的方法就行文檔類別的判斷、轉(zhuǎn)化、展示。
文檔的工作流是EAST文檔管理系統(tǒng)的重要組成部分。一般的文檔管理系統(tǒng)的文檔都是靜態(tài)的,或者是單工作流。EAST的文檔是多區(qū)域科研人員協(xié)同工作的成果,所以文檔的工作流是非靜態(tài),多線路的工作流。圖6是文檔工作流的具體流程。
圖6 文檔工作流圖
由圖6可知,同一個文檔有一個作者,但是可以有一個或多個合作者,所有的作者和合作者可以并行地對文檔進行簽署,所有的簽署完成以后才會進入審批狀態(tài),審批人可以設(shè)置通過,也可以拒絕通過。在整個工作流中,還可以有多個評閱人對文檔進行審閱評論,評閱人只能評論不能更改流程狀態(tài)?;谝陨咸攸c,很容易開發(fā)出基于多通道的文檔工作流。
文檔的版本控制與工作流結(jié)合起來,變成了一個復雜的多通道并行推進的流程。版本工作流狀態(tài)將影響版本更迭過程,current版本必須是所有沒有過時(非obsolete)版本中最成熟的版本,即工作流狀態(tài)級別最高的版本。帶工作流的版本迭代規(guī)則[8]如圖7所示。
圖7 文檔版本控制圖
由圖7可知,帶工作流的版本控制主要分成三個部分。
1) 新建的文檔默認是最新的文檔,也就是current版本。
2) 如果更新文檔,將更新文檔的工作流和該文檔在數(shù)據(jù)庫中最成熟工作流進行比較,如果大于,說明更新的文檔是最讓人滿意的文檔,用更新的文檔替換現(xiàn)在的文檔,并讓current指向更新的文檔,其他文檔都設(shè)置為obsolete;如果小于,說明原來的文檔最讓人滿意,那么current指向不變。
3) 如果數(shù)據(jù)庫中非obsolete文檔的狀態(tài)變化,變化的文檔就相當于2)中更新的文檔,那么回到2)中比較狀態(tài)流成熟度的判定條件來決定current指向哪個文檔。
1) 文檔擴展名檢測。為了保護服務(wù)器的安全,防止惡意程序如exe等非法文件上傳,系統(tǒng)對上傳的文檔類型有嚴格的要求。同時為了避免將exe文件改變拓展名如demo.exe改成demo.txt而被上傳到服務(wù)器,系統(tǒng)會在文檔上傳前用非文檔名的方法判斷擴展名具體實現(xiàn)方式是通過文檔路徑名獲取File實例,并使用getName()方法獲取真實的文檔名稱。獲取到文件名后,用String的endsWith(″.*″)方法判斷是否是指定的文件。其中*可以是doc、pdf等擴展名,如果文檔擴展名是系統(tǒng)限定類型之內(nèi)的,將會通過檢測。
2) 文檔內(nèi)容檢測。文檔上傳前還需要對內(nèi)容進行檢測,是否包含敏感詞匯,是否包含操作數(shù)據(jù)庫特定表的SQL語句。借助于jxl.jar、tm-extractors-0.4.jar等jar包可以對xls、doc等文檔進行解析,并與系統(tǒng)設(shè)置的敏感詞匯,敏感SQL語句模糊匹配,如果沒有查找到,則通過檢測。
3) 文檔上傳。對于已經(jīng)通過檢測的文檔,可以使用基于OKHttp框架的post方式進行文檔上傳。客戶端中的post上傳其實就是模擬了表單提交,只要把發(fā)送的文件信息拼接到頭里面,但是這里的頭信息一定要按照規(guī)范格式去寫,OKHttp中的addFormDataPart(String name, String filename, RequestBody body)方法,已經(jīng)實現(xiàn)了具體格式的封裝,按要求傳入即可完成上傳操作。
文檔的下載過程中,服務(wù)器端通過下載函數(shù)接口隱藏文檔在服務(wù)器的真實路徑,下載的路徑設(shè)置為url+下載函數(shù)+文檔標識符eid+文檔版本號。例如需要下載文檔的eid為AAAA,版本號為2.0的文檔的下載路徑為https://edm.ipp.ac.cn/file_download/AAAA/2.0。該方法規(guī)避了客戶端必須獲取文檔真實路徑的來下載文檔的風險。
考慮到EAST文檔下載后的安全性,不能將普通數(shù)據(jù)與EAST數(shù)據(jù)混合存儲,在開發(fā)中主要用到Android中的context.getExternalFileDir(String type)方法,將文檔存儲在客戶端包名下的files文檔目錄下。這個目錄理論上別的應(yīng)用是無法訪問的,也就不會導致信息泄。但是Android系統(tǒng)很多都被root過,獲得root權(quán)限的惡意應(yīng)用仍然有可能獲取文檔的內(nèi)容,所在下載之后,對文檔進行了MD5加密措施,雙重保護文檔。
當需要查看文檔的時候,開啟輔助線程,將文檔復制到sdcard公用目錄中,然后進行解密操作,最后使用intent.setDataAndType(Uri.fromFile(new File(filename)), "application/*")方法來打開對應(yīng)文檔。當客戶端退出時候,會強制刪除sdcard公用目錄中的文檔。
系統(tǒng)的登錄、多語言的支持、快捷方式的創(chuàng)建、文檔的查詢刪除、文檔的評論等功能,都是基于OKhttp開源框架與服務(wù)器的可靠通信。如果數(shù)據(jù)在無加密的傳輸通道或以明文方式進行傳輸,使得數(shù)據(jù)容易被監(jiān)聽或篡改[9]。為了保證通信的可靠性,服務(wù)器由http升級為https,同時還在參數(shù)中使用約定的加密參數(shù)[10],確保訪問者是已知用戶??蛻舳双@取到服務(wù)器的json格式數(shù)據(jù),對數(shù)據(jù)解析,并顯示在客戶端中,類似的方法,可以實現(xiàn)客戶端的其他基本功能。
EAST文檔數(shù)據(jù)的安全性是系統(tǒng)設(shè)計過程中的重要部分,因此對PHP接口和本地文檔進行了單獨測試。對于本地下載的文檔,使用了已經(jīng)root和沒有root兩部手機測試。結(jié)果表明,雖然已經(jīng)root的手機可以訪問本地文檔,但是因為經(jīng)過加密操作,打開的文檔為亂碼。沒有root的手機,無法訪問到本地文檔,系統(tǒng)在一定程度上保證了安全性。
為了保證科研人員高并發(fā)使用Android平臺的EAST文檔管理系統(tǒng),需要進行壓力測試。在某個客戶端中開啟1 000個線程訪問服務(wù)器,同時使用部分真機和虛擬機一起訪問服務(wù)器,測試結(jié)果表現(xiàn)良好,真機訪問并沒有因為其他設(shè)備訪問而受到影響。
性能測試工具采用了網(wǎng)易公司的Emmagee工具。它是網(wǎng)易公司開發(fā)的一個Android性能檢測工具,主要檢測APP的CPU占用率,內(nèi)存占用率和流量使用情況,同時開發(fā)者可以自定義配置監(jiān)控的頻率并顯示結(jié)果,最終生成一份性能統(tǒng)計文件[11]。
本文使用的是Emmagee2.5.1版本軟件,對基于Android平臺的EAST文檔管理系統(tǒng)就行性能檢測。Emmagee工具生成的是csv格式文本,可以先導入到Excel中,再生成相應(yīng)的圖表。Emmagee檢測報告單如圖8所示,基于檢測報告單的CPU使用率,如圖9所示。
圖9 CPU使用率
由圖8可知,客戶端的流量損失量低,當沒有文檔的上傳下載時候基本不耗流量。由圖9可知,客戶端在使用階段,CPU占有率處于合理位置,不需要消耗過多的系統(tǒng)資源,系統(tǒng)可靠性強,流量穩(wěn)定,電量消耗少,總體來看系統(tǒng)可以滿足科研人員的正常使用。
為了滿足與EAST相關(guān)的科研人員快速準確地獲取文檔信息,本文設(shè)計開發(fā)了基于Android平臺的EAST文檔管理系統(tǒng),并保證通信安全,文檔存儲安全的前提下,對EAST文檔進行工作流控制、版本控制、以及文檔上傳、下載、查詢、刪除等基本操作。系統(tǒng)整體設(shè)計高效安全兼容性好,文檔類的繼承關(guān)系使得文檔類型的可擴展性強。基于Android平臺的EAST文檔管理系統(tǒng)已經(jīng)在實驗中使用,并收到了良好的預(yù)期效果。