Tích hợp FileNet với IBM Content Manager, Phần 2: Triển khai thực hiện các thực thể nghiệp vụ Java và lớp cổng (gateway) cho dữ liệu trong kho lưu trữ lưu trữ của IBM Content Manager

Phần 1 của loạt bài này đã giới thiệu cho bạn về các kiến trúc của FileNet P8 BPM và IBM Content Manager. Bài viết đã sử dụng một hệ thống Yêu cầu bồi thường bảo hiểm tự động của công ty ABC hư cấu để cho bạn thấy cách tích hợp hai sản phẩm mạnh mẽ này. Phần 2 giới thiệu các trình di ễn công việc của FileNet P8 và cho bạn thấy cách triển khai thực hiện các thực thể nghiệp vụ Java. Bạn sẽ t ìm hiểu cách tạo ra một lớp cổng Java và xem cách sử dụng tuần tự hóa Java để tránh các hạn chế cụ thể.

pdf11 trang | Chia sẻ: lylyngoc | Lượt xem: 1604 | Lượt tải: 1download
Bạn đang xem nội dung tài liệu Tích hợp FileNet với IBM Content Manager, Phần 2: Triển khai thực hiện các thực thể nghiệp vụ Java và lớp cổng (gateway) cho dữ liệu trong kho lưu trữ lưu trữ của IBM Content Manager, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
Tích hợp FileNet với IBM Content Manager, Phần 2: Triển khai thực hiện các thực thể nghiệp vụ Java và lớp cổng (gateway) cho dữ liệu trong kho lưu trữ lưu trữ của IBM Content Manager Mở đầu Phần 1 của loạt bài này đã giới thiệu cho bạn về các kiến trúc của FileNet P8 BPM và IBM Content Manager. Bài viết đã sử dụng một hệ thống Yêu cầu bồi thường bảo hiểm tự động của công ty ABC hư cấu để cho bạn thấy cách tích hợp hai sản phẩm mạnh mẽ này. Phần 2 giới thiệu các trình diễn công việc của FileNet P8 và cho bạn thấy cách triển khai thực hiện các thực thể nghiệp vụ Java. Bạn sẽ tìm hiểu cách tạo ra một lớp cổng Java và xem cách sử dụng tuần tự hóa Java để tránh các hạn chế cụ thể. Về đầu trang Các trình diễn công việc Để sử dụng một kho lưu trữ nội dung của bên thứ ba, FileNet Business Process Management (BPM) cần có khả năng giao tiếp với kho lưu trữ IBM Content Manager. Các trình diễn công việc FileNet có thể cho phép BPM tương tác với các ứng dụng hoặc các mã của bên thứ ba. Trong FileNet P8, các trình diễn công việc cho phép một ứng dụng thực hiện một hoạt động hoặc một tập các hoạt động liên quan đến một dòng công việc. Thông thường, các trình diễn công việc được thiết kế không có giao diện người dùng và được sử dụng để thực hiện các hoạt động dòng công việc tự động, chẳng hạn như các hoạt động được liên kết với một bước dòng công việc cụ thể trong một định nghĩa dòng công việc. Các hoạt động trình diễn công việc được liên kết với các bước dòng công việc bao gồm đăng nhập và thiết lập một phiên làm việc của máy quy trình, thăm dò một hàng đợi người dùng hoặc hàng đợi hệ thống (cố gắng để tìm các hoạt động liên quan đến một bước dòng công việc cụ thể), khóa các đối tượng được lấy ra, xử lý công việc (cập nhật dữ liệu và v.v..) và quay ngược để thăm dò hàng đợi. Đại khái là, các trình diễn công việc cần thiết để tương tác với các ứng dụng của bên thứ ba. Có hai kiểu trình diễn công việc, dựa vào trình tích hợp thành phần và dựa trên trình tiện ích nền sau (daemon). Trình diễn công việc dựa vào nhà tích hợp thành phần được dùng trong ví dụ này. Các trình diễn công việc dựa vào nhà tích hợp thành phần là một thành phần được triển khai thực hiện như một lớp Java hoặc sự kiện Java Messaging Service (JMS-Dịch vụ gửi thông báo Java). Một thành phần Java có thể được sử dụng để thực hiện tất cả các hoạt động liên quan đến một dòng công việc. Hình 1 minh họa kiến trúc của nhà tích hợp thành phần: Hình 1. Kiến trúc Nhà tích hợp thành phần FileNet P8 Thành phần Java hoặc JMS có thể được nhà quản lý thành phần (component manager) quản lý. Nhà quản lý thành phần cấu hình và giao tiếp với các bộ điều hợp dịch vụ. Trong thời gian chạy, nhà quản lý thành phần thăm dò các hàng đợi thành phần về các mục công việc đòi hỏi JMS hoặc xử lý bởi các thành phần Java và kết nối một mục công việc đang đòi hỏi một thành phần tới bộ điều hợp dịch vụ thích hợp. Bộ điều hợp Java xử lý các cuộc gọi quy trình cho các đối tượng Java, được biểu diễn đến máy quy trình như là các hoạt động trên các hàng đợi (các mục công việc) ở nơi mỗi hoạt động được thực hiện bằng một phương thức của lớp Java. Bộ điều hợp Java thực hiện ghép nối với thành phần Java, sau đó tự động chờ đáp ứng từ thành phần này, cập nhật mục công việc và gửi mục công việc này đến bước dòng công việc tiếp theo. Bộ điều hợp JMS đặt các thông báo vào Hàng đợi JMS (Queue JMS) và gửi đi mục công việc liên quan. Bộ điều hợp JMS xử lý quy trình gửi lên các sự kiện tới một hàng đợi thông báo (dưới dạng một sự kiện XML dựa trên phần tử bước cho hoạt động cụ thể). Về đầu trang Triển khai thực hiện các thực thể nghiệp vụ Java cho Công ty ABC Công ty ABC muốn lưu trữ tất cả dữ liệu nội dung trong IBM Content Manager hiện có. Và nó cũng muốn sử dụng FileNet BPM để xây dựng một ứng dụng tập trung quy trình. Vì vậy bạn cần triển khai thực hiện các trình diễn công việc trong BPM để thao tác nội dung trong IBM Content Manager hiện có. Bạn có thể gói logic ứng dụng bên thứ ba và trưng ra giao diện đó khi triển khai thực hiện thành phần Java. Với trường hợp của Công ty ABC, trước tiên bạn triển khai thực hiện các thực thể nghiệp vụ Java có thể truy cập dữ liệu trong IBM Content Manager. Hình 2 cho thấy kiến trúc của các thực thể nghiệp vụ Java : Hình 2. Kiến trúc các thực thể nghiệp vụ Java Như kiến trúc này cho thấy, bạn có thể tạo các đối tượng chuyển giao dữ liệu (DTO) và đối tượng truy cập dữ liệu (DAO) phù hợp với mỗi lớp trong biểu đồ lớp (Phần 1; Hình 4). Khi lấy lớp "AutoClaim" làm ví dụ, chúng ta đã tạo ra một lớp DTO AutoClaim.java và một lớp DAO AutoClaimDAO.java. Mã Java sau đây là AutoClaim.java. Nó bao gồm các định nghĩa đặc tính và các phương thức getter và setter có liên quan. Nó biểu diễn giá trị dữ liệu cho một mục trong kho lưu trữ IBM Content Manager. Liệt kê 1. DTO mẫu - AutoClaim.java public class AutoClaim { public AutoClaim () { } private String claimID; public String getClaimID() { return this.claimID; } public void setClaimID(String claimID) { this.claimID = claimID; } private Integer claimStatus; public Integer getClaimStatus() { return this.claimStatus; } public void setClaimStatus(Integer claimStatus) { this.claimStatus = claimStatus; } private String openingDate; public String getOpeningDate() { return this.openingDate; } public void setOpeningDate(String openingDate) { this.openingDate = openingDate; } private Integer claimAmount; public Integer getClaimAmount() { return claimAmount; } public void setClaimAmount(Integer claimAmount) { this.claimAmount = claimAmount; } private String eventID; public String getEventID() { return this.eventID; } public void setEventID(String eventID) { this.eventID = eventID; } private String pidString; public String getPidString() { return pidString; } public void setPidString(String pidString) { this.pidString = pidString; } } Mã Java sau đây là AutoClaimDAO.java là một đối tượng truy cập dữ liệu. Nó chứa tất cả các phương thức gọi OOAPI của IBM Content Manager để xử lý dữ liệu trong IBM Content Manager. Liệt kê 2. DAO mẫu - AutoClaimDAO.java public class AutoClaimDAO { private String itemType; public AutoClaimDAO() { itemType = "AutoClaim"; } public String create(AutoClaim autoClaim) throws DKException, Exception { String pidString = null; DKDatastoreICM dsICM = SConnectDisconnectICM.connect(); DKDDO ddo = dsICM.createDDO("AutoClaim", DKConstant.DK_CM_ITEM); setAttrToDDO(ddo, autoClaim); ddo.add(); pidString = ddo.getPidObject().pidString(); dsICM.disconnect(); return pidString; } public AutoClaim retrieveAutoClaimByClaimID(String claimID) throws DKUsageError, DKException, Exception { AutoClaim autoClaim = null; String queryString = "/AutoClaim[@Claim=\""+claimID+"\"]"; DKDatastoreICM dsICM = SConnectDisconnectICM.connect(); dkIterator dkIter = (dkIterator) SConnectDisconnectICM.search(dsICM, queryString, 0, true); if(dkIter.more()) { autoClaim = new AutoClaim(); DKDDO ddo = (DKDDO)dkIter.next(); ddo.retrieve(DKConstant.DK_CM_CONTENT_ITEMTREE + DKConstant.DK_CM_CONTENT_NO); setValueToAutoClaim(ddo, autoClaim); autoClaim.setPidString( ddo.getPidObject().pidString() ); } dsICM.disconnect(); return autoClaim; } public void update(String pidString, AutoClaim autoClaim) throws DKUsageError, DKException, Exception { DKDatastoreICM dsICM = SConnectDisconnectICM.connect(); DKDDO ddo= dsICM.createDDO(pidString); ddo.retrieve(DKConstant.DK_CM_CONTENT_ITEMTREE + DKConstant.DK_CM_CONTENT_NO); DKDatastoreExtICM ext = new DKDatastoreExtICM(dsICM); if(!ext.isCheckedOut(ddo)) { ext.checkOut(ddo); } setAttrToDDO(ddo, autoClaim); dsICM.updateObject(ddo, DKConstant.DK_CM_CHECKIN); dsICM.disconnect(); } public void delete(String pidString) throws DKUsageError, DKException, Exception { DKDatastoreICM dsICM = SConnectDisconnectICM.connect(); DKDDO ddo = dsICM.createDDO(pidString); ddo.del(); dsICM.disconnect(); } public void setAttrToDDO(DKDDO ddo, AutoClaim autoClaim) throws DKUsageError { if(autoClaim.getClaimID()!=null) ddo.setData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,"ClaimID"), autoClaim.getClaimID()); if(autoClaim.getClaimStatus()!=null) ddo.setData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,"ClaimStatus"), autoClaim.getClaimStatus()); if(autoClaim.getOpeningDate()!=null) ddo.setData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,"OpeningDate"), autoClaim.getOpeningDate()); if(autoClaim.getClaimAmount()!=null) ddo.setData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,"ClaimAmount"), autoClaim.getClaimAmount()); if( autoClaim.getEventID() != null ) ddo.setData( ddo.dataId( DKConstant.DK_CM_NAMESPACE_ATTR, "EventID" ), autoClaim.getEventID() ); } public void setValueToAutoClaim(DKDDO ddo, AutoClaim autoClaim) throws DKUsageError { Object attr = null; attr = ddo.getData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR, "ClaimID")); if(attr!=null) { autoClaim.setClaimID((String)attr); attr = null; } attr = ddo.getData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR, "ClaimStatus")); if(attr!=null) { autoClaim.setClaimStatus((Integer)attr); attr = null; } attr = ddo.getData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR, "OpeningDate")); if(attr!=null) { autoClaim.setOpeningDate((String)attr); attr = null; } attr = ddo.getData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR, "ClaimAmount")); if(attr!=null) { autoClaim.setClaimAmount((Integer)attr); attr = null; } attr = ddo.getData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR, "EventID")); if(attr!=null) { autoClaim.setEventID( (String) attr ); attr = null; } } ... } Đối với các lớp khác trong biểu đồ lớp, có các lớp Java tương tự như AutoPolicy.java và AutoPolicyDAO.java. Bạn có thể tải về dự án Eclipse có chứa tất cả mã nguồn của lớp Java này. Về đầu trang Triển khai thực hiện lớp cổng cho các thực thể nghiệp vụ Java Bây giờ bạn đã có một tập hợp các thực thể nghiệp vụ Java và cũng có rất nhiều phương thức hoạt động trong các thực thể này. Nhưng trong phần FileNet Component Integrator (Nhà tích hợp thành phần FileNet), một hàng đợi thành phần chỉ có thể trưng ra một phương thức của lớp Java. Và bạn nên tuân theo các quy tắc sau đây:  Lớp phải có một hàm tạo không có bất kỳ tham số nào.  Các phương thức phải được công khai.  Các phương thức có thể chỉ chứa các kiểu tham số hoạt động thành phần cho phép. Hãy tham chiếu các kiểu tham số hoạt động thành phần. Nếu bạn muốn tương tác với nhiều lớp Java từ một ứng dụng của bên thứ ba và muốn đăng ký chỉ có một hàng đợi thành phần cho ứng dụng này, thì bạn nên bọc tất cả các phương thức của các lớp Java trong một lớp cổng (gateway). Vì thế với hệ thống Yêu cầu bồi thường bảo hiểm tự động của Công ty ABC, bạn nên bọc tất cả các phương thức hoạt động DAO trong một lớp cổng -- ICMOperation.java -- thể hiện trong mã Java sau. Liệt kê 3. Lớp của trình bao bọc mẫu - ICMOperation.java public class ICMOperation { public void createAutoClaim(String claimID,Integer claimStatus, String openingDate,Integer claimAmount, String eventID) throws Exception { AutoClaim autoClaim = new AutoClaim(); autoClaim.setClaimID(claimID); autoClaim.setClaimStatus(claimStatus); autoClaim.setOpeningDate(openingDate); autoClaim.setClaimAmount(claimAmount); autoClaim.setEventID( eventID ); AutoClaimDAO dao = new AutoClaimDAO(); dao.create( autoClaim ); } public Integer retrieveClaimStatusByClaimID(String claimID) throws Exception { AutoClaim autoClaim = getAutoClaim( claimID ); return autoClaim.getClaimStatus(); } public void updateClaimStatusByClaimID( String claimID, Integer claimStatus ) throws Exception { AutoClaimDAO dao = new AutoClaimDAO(); AutoClaim autoClaim = dao.retrieveAutoClaimByClaimID( claimID ); autoClaim.setClaimStatus( claimStatus ); dao.update( autoClaim ); } private AutoClaim getAutoClaim( String claimID ) throws Exception { return new AutoClaimDAO().retrieveAutoClaimByClaimID( claimID ); } ... } Về đầu trang Một cách giải quyết sử dụng các tham số đối tượng Java khác trong Component Integrator FileNet P8 Component Integrator (Nhà tích hợp thành phần FileNet P8) chỉ hỗ trợ một số kiểu tham số nguyên thủy. Nhưng nói chung, một số đối tượng Java luôn được sử dụng như các tham số trong một phương thức hoạt động. Ở đây, chúng ta đã giới thiệu một giải pháp để khắc phục hạn chế này: sự tuần tự hóa Java. Hình 3 cho thấy giải pháp này. Hình 3. Giải pháp tuần tự hóa Java Khi sử dụng tuần tự hóa Java, bạn có thể tuần tự hóa đối tượng Java ban đầu thành một chuỗi trong bộ nhớ. Khi bạn cần nhận đối tượng Java ban đầu, bạn có thể không tuần tự hóa chuỗi đó thành đối tượng Java ban đầu. Hãy lấy AutoClaimDAO.java làm ví dụ. Nếu bạn muốn sử dụng DTO AutoClaim.java làm tham số trong các phương thức hoạt động, bạn cần phải viết hai phương thức tiện dụng. Một phương thức là để tuần tự hóa đối tượng Java AutoClaim thành một chuỗi, trong khi phương thức kia là không tuần tự hóa chuỗi đó thành đối tượng Java AutoClaim ban đầu. Các đoạn mã Java dưới đây cho thấy hai phương thức này. Liệt kê 4. Mã mẫu về tuần tự hóa và không tuần tự hóa public AutoClaim parseStringToAutoClaim( String autoClaimString ) throws IOException, ClassNotFoundException { ObjectInputStream objInput = null; try { objInput = new ObjectInputStream( new ByteArrayInputStream( new BASE64Decoder().decodeBuffer( autoClaimString ) ) ); return (AutoClaim) objInput.readObject(); } finally if( objInput != null ) { objInput.close(); } } } public String parseAutoClaimToString( AutoClaim autoClaim ) throws IOException { ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(); ObjectOutputStream objOutput = null; try { objOutput = new ObjectOutputStream( byteOutput ); objOutput.writeObject( autoClaim ); return new BASE64Encoder().encode( byteOutput.toByteArray() ); } finally { byteOutput.close(); if( objOutput != null ) { objOutput.close(); } } } Sau đó bạn nên làm cho AutoClaim có thể tuần tự hóa được. Điều cần thiết duy nhất là để cho AutoClaim triển khai thực hiện giao diện java.io.Serializable. Mã sau đây cho thấy AutoClaim có thể tuần tự hóa. Liệt kê 5. Mã mẫu triển khai thực hiện tuần tự hóa public class AutoClaim implements Serializable{ private static final long serialVersionUID = 4599855634813333505L; ... } Bây giờ bạn có thể đăng ký phương thức sử dụng chuỗi để biểu diễn đối tượng Java. Và trong ứng dụng khách, bạn nên sử dụng phương thức không tuần tự hóa để nhận đối tượng Java ban đầu. Hãy xem đoạn mã sau. Chúng ta sử dụng một phương thức trong lớp ICMOperation đã đăng ký để lấy ra đối tượng Java AutoClaim. Sau khi có kết quả, đầu tiên sử dụng phương thức tuần tự hóa để tuần tự hóa đối tượng Java AutoClaim thành một đối tượng chuỗi, sau đó trả về chuỗi cho một máy khách. Một khi máy khách nhận được chuỗi đó, sử dụng phương thức không tuần tự hóa để không tuần tự hóa chuỗi đó thành một đối tượng AutoClaim. Liệt kê 6. Mã mẫu xem xét xung quanh sự hạn chế tham số public String retrieveAutoClaimByClaimID( String claimID ) throws Exception { AutoClaim autoClaim = getAutoClaim( claimID ); return new AutoClaimDAO().parseAutoClaimToString( autoClaim ); } Bây giờ chúng ta có các thực thể nghiệp vụ Java và một lớp cổng Java trưng ra tất cả các phương thức hoạt động. Bạn có thể tải về tất cả các mã nguồn trong một dự án Java của Eclipse. Lưu ý rằng mức tuân thủ của trình biên dịch nên được đặt là 1.4 khi tạo các tệp jar tương ứng do sự tương thích của nhà tích hợp thành phần.